Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Built-in SVG components #699

Closed
natemoo-re opened this issue Sep 13, 2023 · 12 comments
Closed

Built-in SVG components #699

natemoo-re opened this issue Sep 13, 2023 · 12 comments

Comments

@natemoo-re
Copy link
Member

Summary

Let's support importing and using .svg files as Astro components.

Background & Motivation

Users have reported that .svg files are currently difficult to use—this is a problem we should provide an optimized solution for. Working with .svgs doesn’t need to be difficult or bloat your client-side JavaScript.

The Astro team has discussed and experimented with an "icon" primitive since before Astro v1.0 shipped. Now that we have shipped 3.0 with full astro:assets support, I firmly believe all of the pieces are in place to finally make this happen.

Goals

  • Allow users to import and render local .svg files as if they were an Astro component
  • Allow passing props onto the root <svg> element while overriding the existing props
  • Automate best practices for to minimize performance footguns
    • Including many inlined <svg> on a page can hurt browser parsing performance. We can automatically reduce the number of nodes by using <symbol> and <use>.
    • Inline <svg> often have xmlns and xmlns:xlink and version attributes. These are not needed in HTML5 and we can automatically drop them to save a few bytes.
  • Support this in a backwards-compatible way, meaning the current public interface of an .svg import remains unchanged
  • Stretch: support rendering .svg components in frameworks without inlining them into the client side JavaScript
    • Creating framework components for .svg icons is an anti-pattern. It’s a terrible idea that bloats your JavaScript and creates all sorts of headaches for HMR and clientside performance in production.
    • If we provide a great <Icon> component for each supported framework, we’ll make it easy for users to avoid this anti-pattern. It’s so common now because there aren’t many other good solutions.

Non-Goals

  • Future: @iconify/json support
  • Future: unplugin-icons support? Making this as seamless as possible would be awesome but supporting local .svg files is a good place to start.
@gvkhna
Copy link

gvkhna commented Sep 13, 2023

Please support promise imports, like src={import(‘file.svg’)}. Please, thank you!

+1, “ provide a great component for each supported framework”. I still don’t know how to in-line svg files with react/vite, always very brittle, end up copy pasting. 👍

@stramel
Copy link

stramel commented Oct 12, 2023

Would love to see the ability to extend the built-in SVG support for icon sets in the future using something like @iconify/json.

I also think that framework support would be a good Goal. We get lots of questions about how to use icons within frameworks. Typically this has been solved using slots

@azat-io
Copy link

azat-io commented May 7, 2024

It's something I'm really looking forward to. ❤️

The main problem with importing via <Fragment set:html={HomeIcon} /> is the inability to use CSS classes with inlined SVGs.

What will importing SVG files look like?

---
import HomeIcon from '~/icons/home.svg?component'
---

<HomeIcon class="icon" />

@abdo-spices
Copy link

abdo-spices commented Jun 1, 2024

when need it to convert repeated SVGs to be use symbol like astro-icon

@Gismogy
Copy link

Gismogy commented Jul 19, 2024

It's something I'm really looking forward to. ❤️

The main problem with importing via <Fragment set:html={HomeIcon} /> is the inability to use CSS classes with inlined SVGs.

What will importing SVG files look like?

---
import HomeIcon from '~/icons/home.svg?component'
---

<HomeIcon class="icon" />

I was actually more thinking for its own tag like Picture has its own picture tag.
Might that be a idea?

@cxa
Copy link

cxa commented Jul 22, 2024

Before this builtin component is out, and if you don't like to save svg copies inside places like src/icons with astro-icon, you can try https://github.com/cxa/astro-inline-svg:

---
import Svg from "@cxa/astro-inline-svg";
import sunRiseSVG from "lucide-static/icons/sunrise.svg?raw";
---

<Svg raw={sunRiseSVG} class="sun-rise" stroke-width={1.5} />

@stramel
Copy link

stramel commented Sep 25, 2024

Hey everyone, I have spoken with @natemoo-re about carrying this proposal through to the finish line. Turns out that Nate had done a lot of the work, I'm mostly just cleaning up and making sure everything works as intended.

I have opened a draft PR for the changes to implement this: withastro/astro#12067

I also help maintain astro-icon with Nate (although, I've been slacking lately) and we can build upon this feature to implement automatic Iconify virtual imports through that package as demoed here: natemoo-re/astro-icon#239

Looking for guidance as to next official steps for getting this moving forward again! Who could help me with this? @natemoo-re @FredKSchott @bholmesdev

@ematipico
Copy link
Member

Thank you @stramel! Your efforts and work are really appreciated, and we will make sure to help you to bring the feature to the finish line.

As a first step, we require a Stage 3 RFC before shipping the feature as experimental. This means that we can start reviewing the PR, but once the we are ready for merging it, the Stage 3 RFC needs to be ready.

Let us know if you have time and resources to write it, and we will plan accordingly.

@azat-io
Copy link

azat-io commented Oct 1, 2024

Will there be a built-in SVGO for SVG minification?

@stramel
Copy link

stramel commented Oct 2, 2024

Thank you @stramel! Your efforts and work are really appreciated, and we will make sure to help you to bring the feature to the finish line.

As a first step, we require a Stage 3 RFC before shipping the feature as experimental. This means that we can start reviewing the PR, but once the we are ready for merging it, the Stage 3 RFC needs to be ready.

Let us know if you have time and resources to write it, and we will plan accordingly.

Thank you! ❤️ I will work on building out the Stage 3 RFC shortly and work on getting the valuable feedback from everyone addressed here!

Will there be a built-in SVGO for SVG minification?

I think in the initial scope, we're omitting this in the core. However, I have done some playing around with adding an SVGO image service which seems like a good direction for us in the future steps to enhance this.

@stramel
Copy link

stramel commented Oct 2, 2024

@ematipico Threw together a rough pass at a Stage 3 RFC: #1035

/cc @natemoo-re

@ematipico
Copy link
Member

Thank you @stramel.

For anyone subscribed to this issue, I suggest continuing the conversation at #1035

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: Stage 3: Accepted Proposals, Has RFC
Development

No branches or pull requests

8 participants