-
-
Notifications
You must be signed in to change notification settings - Fork 2.3k
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
Add React component SSR #28
Conversation
drwpow
commented
Mar 25, 2021
•
edited
Loading
edited
src/compiler/index.ts
Outdated
} | ||
children = [...styleTags, ...(children || [])]; | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is where I’m struggling a bit to inject the styles back in the HTML. I know this is the wrong place, but I’m a bit lost where the right place is.
request.styles
has the correct URLs… I just can’t seem to inject the <link />
tags.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So if you look at most pages, this is because they don't define a slot
so children have no where to go. Really only components and layouts use <slot>
. Since pages are the top-level thing, there's no expectation of being filled with any children.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
tbh I'd suggest just injecting these into the final page HTML, via a regex, in runtime.ts
:
const mod = await snowpackRuntime.importModule(selectedPageUrl);
let html = (await mod.exports.__renderPage({...})) as string;
html = html.replace(`</head>`, mod.css.map(href => `<link rel="stylesheet" type="text/css" href="\${href}" />`);
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the idea of automatically inserting them into the head
inside of __renderPage()
-- when all you have is a bunch of h()
calls -- will require a bit of non-trivial work, probably either:
- adding back the idea of a special
astro:head
component, specifically for adding things to the head. - adding a named
<slot name="astro:head">
that's automatically added to the end of every head, and then adding support for named slots. - passing styles into the render function, and then somehow compiling pages to add a special fragment element that checks for this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is one of the reasons for having the optimize step. I would append something like <Fragment>{styles.map(css => <style>{css}</style>}</Fragment>
(as AST nodes) to the head in an optimizer. At runtime this code will need access to the styles
variable. So we have to make sure that exists in scope. (not sure how you're doing this now)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nope:
export default __render;
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But for pages is that ever called externally? runtime.ts only calls __renderPage
. I don't think anything is importing the default and calling it for pages.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ohhhhhhh interesting....... yea good point! That could be worth exploring (although @drwpow there are some bigger implications there, would definitely recommend leaving as-is for this PR if you can help it).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If there's not a ton of duplication it might make things more readable to define pages / components with separate template strings. So you can see in one place everything a page/component does. (not in this pr)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah if it‘s all right, injecting in the HTML in runtime.ts
is the approach I took for now. Also left a TODO
note to clean up later. +1 for moving it out of there eventually, but for now I want to put it in the least disruptive place (even if temporary)
date: '2021-01-12 00:00:00Z', | ||
title: 'Snowpack v3.0', | ||
description: 'Snowpack v3.0 is here!', | ||
}} /> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added a static component here because on the News page, those are :dynamic
cards. Dynamic components seem to work fine, but static ones are what I’m testing.
296ba6e
to
118ddeb
Compare
Going to merge—thanks for the feedback. I think it‘s in a place now where this just adds a stylesheet to the final output where before there was none, and it doesn’t make any disruptive changes (other than that temporary HTML replacement that may be refactored later) |