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

Container APIs #916

Open
wants to merge 11 commits into
base: main
Choose a base branch
from
Open

Container APIs #916

wants to merge 11 commits into from

Conversation

ematipico
Copy link
Member

@ematipico ematipico commented May 6, 2024

Summary

An API for rendering components in isolation:

// Card.test.js
import Card from "../src/components/Card.astro"
import astroConfig from "../src/astro.config.mjs";

const container = await AstroContainer.create()
const response = await container.renderToString(Card);
// assertions

Links

@ematipico ematipico marked this pull request as ready for review May 6, 2024 13:41
ematipico and others added 2 commits May 8, 2024 15:49
Co-authored-by:  Matthew Phillips <matthew@skypack.dev>
proposals/0048-container-api.md Outdated Show resolved Hide resolved
proposals/0048-container-api.md Outdated Show resolved Hide resolved
proposals/0048-container-api.md Show resolved Hide resolved
ematipico and others added 4 commits May 15, 2024 14:57
Co-authored-by: Erika <3019731+Princesseuh@users.noreply.github.com>
Co-authored-by: Erika <3019731+Princesseuh@users.noreply.github.com>
Co-authored-by:  Matthew Phillips <matthew@skypack.dev>
Co-authored-by: Bjorn Lu <bjornlu.dev@gmail.com>
}
```

The `astroConfig` object is literally the same object exposed by the `defineConfig`, inside the `astro.config.mjs` file. This very configuration
Copy link
Contributor

Choose a reason for hiding this comment

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

Have you found use-case for passing the astroConfig yet? I'm worried about getting bug reports when people try to pass through vite config and other non-supported stuff.

What do you think about instead raising the relevant config values up to the AstroContainerOptions level. That would be stuff like trailingSlash.

Copy link
Member Author

Choose a reason for hiding this comment

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

What do you think about instead raising the relevant config values up to the AstroContainerOptions level. That would be stuff like trailingSlash.

I don't think that would work easily. These options, internally, are used to create a manifest. If we pass these options when rendering a component, it would mean generating a new manifest every time we attempt to render a component, and then discard that manifest. We have to be careful not to override the existing manifest, because the manifest is tight to the lifetime of the instance of the container.

Copy link
Contributor

Choose a reason for hiding this comment

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

Not when rendering, AstroContainerOptions is the name of the options passed to AstroContainer.create().

Copy link
Member Author

Choose a reason for hiding this comment

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

Oh, I misunderstood what you meant. Yeah we should be able to provide the individual options.

@tordans
Copy link

tordans commented May 28, 2024

Hey! Can I use the new container API to render const { Content } = await page.render() into a string, pass this string to a React Component and render it there with dangerouslySetInnerHTML? I am looking for a way to render all posts in a blog post index kind of situation (Example) and pass them over to React without loosing all the markdown rendering that Astro does in <Content/>. It sounds like this API might help, but Content is not a component but returned by await page.render() so how does that work?

I tried passing Content but that fails:

const rawPages = await getCollection('posts')
const sortedPages = rawPages.sort((a, b) => a.data.order - b.data.order)
const pages: RadnetzPage[] = []
for (const page of sortedPages) {
  const { Content } = await page.render()
  const container = await AstroContainer.create()
  const result = await container.renderToString(Content)
  pages.push({
    slug: page.slug,
    menu: page.data.menu,
    order: page.data.order,
    title: page.data.title,
    links: page.data.links,
    Content: Content,
    contentHtml: result,
  })
}

Results in…

Unhandled rejection
Astro detected an unhandled rejection. Here's the stack trace:
NoMatchingRenderer: Unable to render Content.

No valid renderer was found for this file extension.
    at renderFrameworkComponent (/…/node_modules/astro/dist/runtime/server/render/component.js:190:15)
    at async Module.renderComponent (…/node_modules/astro/dist/runtime/server/render/component.js:396:10)

(I was directed here from the changelog.)

@ematipico
Copy link
Member Author

ematipico commented May 28, 2024

@tordans yes you can, however you'll have to wait for this PR to be merged and released: withastro/astro#11141

@tordans
Copy link

tordans commented May 29, 2024

@tordans yes you can, however you'll have to wait for this PR to be merged and released: withastro/astro#11141

Perfect, thanks @ematipico.
I noticed that withastro/astro#11141 does not mention any Docs changes (yet) and https://github.com/withastro/docs/pulls?q=is%3Apr+is%3Aopen+container-reference doesn't either (yet). Given that I noticed a lack of docs on the topic of rendering lists – see withastro/docs#8364 – that might be something to show in the docs for this API as well.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants