#What is the prop type of a astro slot inside react?

8 messages · Page 1 of 1 (latest)

heavy cliff
#

see title

keen knotBOT
#

Hi @heavy cliff. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave:

#

When you pass a slot from Astro to a React component (i.e., you use a named slot or default slot as a child of a React component inside an .astro file), Astro will convert the slot content into a React prop. For the default slot, this becomes the children prop; for named slots, the slot name (in camelCase) becomes a prop on the React component.

The type of these slot props in React is typically ReactNode, which is the standard type for children in React. This means you can expect the slot prop (e.g., children, title, socialLinks) to be of type React.ReactNode in your React component.

Example:

---
// src/pages/named-slots.astro
import MySidebar from '../components/MySidebar.jsx';
---
<MySidebar>
  <h2 slot="title">Menu</h2>
  <p>Here is a sidebar with some text and a button.</p>
  <ul slot="social-links">
    <li><a href="<https://twitter.com/astrodotbuild">Twitter</a></li>>
    <li><a href="<https://github.com/withastro">GitHub</a></li>>
  </ul>
</MySidebar>
// src/components/MySidebar.jsx
export default function MySidebar(props) {
  return (
    <aside>
      <header>{props.title}</header>
      <main>{props.children}</main>
      <footer>{props.socialLinks}</footer>
    </aside>
  );
}

In this example, props.title, props.children, and props.socialLinks are all of type React.ReactNode. This is the standard way Astro passes slot content to React components, and you can type them as such in TypeScript:

type MySidebarProps = {
  title?: React.ReactNode;
  children?: React.ReactNode;
  socialLinks?: React.ReactNode;
};
#

This behavior is documented in the Astro guide for passing children and named slots to framework components, specifically React, Preact, and Solid, where slot content is converted to top-level props of type ReactNode Passing children to framework components.

Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:

#

@heavy cliff Kapa.ai is still learning and improving, please let me know how I did by reacting below.

heavy cliff
#

@keen knot

 is not assignable to type 
 .
   

Property header   is missing in type 
 but required in type 
 .

<Gallery>
    <p slot='header'></p>
</Gallery>
import type { ReactNode } from "react";

type Props = {
    header: ReactNode;
};
export const Gallery = ({ header }: Props) => {
    return (
        <section
            id='scenarios'
            className='mb-10'>
            {header}
        </section>
    );
};

keen knotBOT
#

Let me check the knowledge base for you again. One moment! :books:

#

The error you are seeing is because Astro only passes a named slot (like header) as a prop to your React component if that slot is actually provided as a child in the Astro file. If you define your React component’s props as required (i.e., header: ReactNode;), but you use <Gallery> without providing a header slot, TypeScript will complain that the required prop is missing.

In your example:

<Gallery>
    <p slot='header'></p>
</Gallery>

And in your React component:

import type { ReactNode } from "react";

type Props = {
    header: ReactNode;
};
export const Gallery = ({ header }: Props) => {
    return (
        <section id='scenarios' className='mb-10'>
            {header}
        </section>
    );
};

If you do not provide a <p slot='header'>, Astro will not pass the header prop, and TypeScript will complain because header is required.

Solution:
Make the header prop optional in your React component:

type Props = {
    header?: ReactNode;
};

This matches Astro’s behavior, where named slots are only passed if present Passing children to framework components.

Summary:

  • Astro only passes a named slot as a prop if it is present in the Astro file.
  • To avoid TypeScript errors, mark named slot props as optional in your React component’s type definition.

If you need the header slot to always be present, ensure you always provide it in your Astro usage. Otherwise, make the prop optional.

Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: