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

Add React component SSR #28

Merged
merged 2 commits into from
Mar 25, 2021
Merged

Add React component SSR #28

merged 2 commits into from
Mar 25, 2021

Conversation

drwpow
Copy link
Member

@drwpow drwpow commented Mar 25, 2021

Screen Shot 2021-03-25 at 13 39 35

@drwpow drwpow requested a review from FredKSchott March 25, 2021 19:19
}
children = [...styleTags, ...(children || [])];
}

Copy link
Member Author

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.

Copy link
Member

@FredKSchott FredKSchott Mar 25, 2021

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.

Copy link
Member

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}" />`);

Copy link
Member

@FredKSchott FredKSchott Mar 25, 2021

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.

Copy link
Contributor

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)

Copy link
Member

Choose a reason for hiding this comment

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

nope:

export default __render;

Copy link
Contributor

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.

Copy link
Member

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).

Copy link
Contributor

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)

Copy link
Member Author

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!',
}} />
Copy link
Member Author

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.

@drwpow drwpow force-pushed the react-ssr branch 3 times, most recently from 296ba6e to 118ddeb Compare March 25, 2021 19:39
src/runtime.ts Outdated Show resolved Hide resolved
src/compiler/index.ts Outdated Show resolved Hide resolved
@drwpow
Copy link
Member Author

drwpow commented Mar 25, 2021

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)

@drwpow drwpow merged commit 04a443a into main Mar 25, 2021
@drwpow drwpow deleted the react-ssr branch March 25, 2021 22:59
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

3 participants