Skip to content

feat(types): add SvgComponent type and update SVG module declaration - #13651

Merged
ascorbic merged 10 commits into
withastro:mainfrom
ADTC:type-svg-component
Sep 24, 2025
Merged

feat(types): add SvgComponent type and update SVG module declaration#13651
ascorbic merged 10 commits into
withastro:mainfrom
ADTC:type-svg-component

Conversation

@ADTC

@ADTC ADTC commented Apr 18, 2025

Copy link
Copy Markdown
Contributor

Changes

Testing

No tests needed, I think?

Docs

Docs will need to mention that the SvgComponent component is available for use, similar to the mentions of other types like ImageMetadata.

/cc @withastro/maintainers-docs for feedback!

@changeset-bot

changeset-bot Bot commented Apr 18, 2025

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: f600121

The changes in this PR will be included in the next version bump.

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@github-actions github-actions Bot added pkg: astro Related to the core `astro` package (scope) docs pr semver: minor Change triggers a `minor` release labels Apr 18, 2025

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This PR is blocked because it contains a minor changeset. A reviewer will merge this at the next release if approved.

@ADTC

ADTC commented Apr 18, 2025

Copy link
Copy Markdown
Contributor Author

Should this be minor or patch? @florian-lefebvre I was going by the semver definitions ("add [new] functionality") when I chose minor:

MAJOR version when you make incompatible API changes
MINOR version when you add functionality in a backward compatible manner
PATCH version when you make backward compatible bug fixes

But we can change it to patch if desired.

Comment thread packages/astro/client.d.ts Outdated
Comment thread packages/astro/client.d.ts Outdated
Comment thread packages/astro/src/assets/types.ts Outdated
Comment thread packages/astro/src/assets/types.ts Outdated
@florian-lefebvre

Copy link
Copy Markdown
Member

I think this is good as a minor thanks!

@ADTC

ADTC commented Apr 18, 2025

Copy link
Copy Markdown
Contributor Author

Changes done. @florian-lefebvre

Note: I didn't use GitHub UI to accept your suggestions, but rather just replicated them in my local and made a commit to ensure there are no syntax errors and it has proper formatting. :)

@ADTC
ADTC requested a review from florian-lefebvre April 18, 2025 12:34
@ascorbic

Copy link
Copy Markdown
Contributor

This is an expermental feature, so it can be a patch

@ADTC

ADTC commented Apr 19, 2025

Copy link
Copy Markdown
Contributor Author

@ascorbic As per v5.7.0 release notes, the SVG feature is no longer experimental.

Can you clarify again whether this change should be minor or patch?

@ascorbic

Copy link
Copy Markdown
Contributor

🤦‍♂️ You're right of course. In my defence is been a long week with lots of features

@ADTC
ADTC requested a review from Princesseuh April 21, 2025 15:10
@ematipico ematipico added this to the v5.8.0 milestone May 19, 2025
@ematipico

Copy link
Copy Markdown
Member

@ADTC maintainers are responsible for documenting the features they implement. This means that you will have send a PR to withastro/docs.

Also, the Build is falling, so we can't merge it until this is fixed.

@ADTC

ADTC commented May 19, 2025

Copy link
Copy Markdown
Contributor Author

Yes I know the build is failing but I don't know how to fix it. 😢 I was hoping @Princesseuh might have some insight.

@Princesseuh

Copy link
Copy Markdown
Member

I'm not sure, sorry. It has been too much time since I've set up client.d.ts and all of that to remember the exact rules that make TypeScript happy. In retrospect, maybe astro-jsx.d.ts shouldn't have lived "outside" of the package, it's wonky, but I set that up 3 years ago now 😅

@ematipico ematipico removed this from the v5.8.0 milestone May 20, 2025
@github-actions github-actions Bot removed the docs pr label Sep 16, 2025
@florian-lefebvre florian-lefebvre added this to the v5.14.0 milestone Sep 16, 2025
@florian-lefebvre
florian-lefebvre removed the request for review from Princesseuh September 16, 2025 14:03
@sarah11918

Copy link
Copy Markdown
Member

We're going to need docs for this one! I'm going to enlist the help of @ArmandPhilippot here! 😄

@florian-lefebvre

Copy link
Copy Markdown
Member

Let me know if I can help in any way!

@ArmandPhilippot

ArmandPhilippot commented Sep 23, 2025

Copy link
Copy Markdown
Member

I think we can describe the type in Type utilities and maybe add Type: SvgComponent with a link in SVG components.

However, I'm not sure how to describe it... because, as I understand it, the use case is to pass an imported SVG as a component via props. But, we only document passing components with slots, not as props. While it works with some components (like <Content />), we don't document it.
So, if we show that, wouldn't it be confusing? Some users might expect be able to pass other components as props?

Maybe we could describe the type using what we document in Common prop type patterns?

If your component must be passed children to its default slot, you can enforce this by using type Props = { children: any; };.

Something like:

// component-a.astro
---
import type { SvgComponent } from "astro/types";

type Props = {
  children: SvgComponent;
}
---

<div><slot /></div>
// component-b.astro
---
import ComponentA from "./component-a.astro";
import MyLogo from "../assets/logo.svg";
---

{/* This would work: */}
<ComponentA><MyLogo /></ComponentA>

{/* This won't work, Typescript will complain: */}
<ComponentA>Anything except an imported SVG.</ComponentA>
{/* 'ComponentA' components don't accept text as child elements. Text in JSX has the type 'string', but the expected type of 'children' is 'SvgComponent'.ts(2747) */}

@florian-lefebvre

Copy link
Copy Markdown
Member

If we need examples, I think something about a user menu would be better:

import type { SvgComponent } from "astro/types";
import HomeIcon from './Home.svg'

interface Link {
	url: string
	text: string
	icon: SvgComponent
}

const links: Link[] = [
	{
		url: '/',
		text: 'Home',
		icon: HomeIcon
	}
]

@sarah11918

Copy link
Copy Markdown
Member

OK, so some thoughts:

  • Florian's example looks helpful, and easy to see how it's used.
  • The "Type Utilities" section on the TypeScript guide feels like these are very general, broad things and this feels very specific. I don't immediately see how this fits there (which doesn't mean it doesn't belong, just that I can't see how this fits in)
  • Are there more analogous things like this? If so, where are they documented?
  • Could we maybe even just get away with something minimal, like Florian's example, in the SVG Components section of the Images guide, as a "And, here's how to type them..." sub-section? This content is arguably only useful to that section of docs and a usage example right there might be all we need?

@florian-lefebvre

Copy link
Copy Markdown
Member

I think your suggestion makes a lot of sense Sarah

@sarah11918

sarah11918 commented Sep 23, 2025

Copy link
Copy Markdown
Member

I'm thinking something like what we do in the Layouts guide maybe? We explain creating layout components (how they wrap, slots etc.) and then have a Using TypeScript with layouts section which is basically that... OK, you made a layout. If you additionally want type safety, here's what it looks like to type things.

We could use this as a model for adding a sub-section, so the flow goes like:

### SVG Components

#### SVG component attributes

#### `SVGComponent` Type

@ArmandPhilippot

Copy link
Copy Markdown
Member

I agree Florian's example looks better! I guess I was too focused on the "using them as props" concern, but this can be done in the same component.

I think the "Type utilities" section is the only place where we document types from astro/types that's why I suggested that. But, I agree, this is probably not the best place because we describe generic types there.

So, yes, a new sub-section in SVG components may be enough!

@florian-lefebvre

Copy link
Copy Markdown
Member

FYI I initially wanted to export the type from astro instead of astro/types, but looks like it's not possible for some reason

@sarah11918

Copy link
Copy Markdown
Member

OK, added a first attempt here! Let's continue the docs discussion there! withastro/docs#12406

Comment thread .changeset/shy-heads-know.md Outdated
florian-lefebvre and others added 2 commits September 24, 2025 13:33
Co-authored-by: Sarah Rainsberger <5098874+sarah11918@users.noreply.github.com>
@ascorbic
ascorbic merged commit dcfbd8c into withastro:main Sep 24, 2025
20 checks passed
@astrobot-houston astrobot-houston mentioned this pull request Sep 25, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

pkg: astro Related to the core `astro` package (scope) semver: minor Change triggers a `minor` release

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants