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

Question: What do you mean by "Meaningful content". #2

Open
gijsroge opened this issue May 31, 2018 · 1 comment
Open

Question: What do you mean by "Meaningful content". #2

gijsroge opened this issue May 31, 2018 · 1 comment
Labels
question Further information is requested

Comments

@gijsroge
Copy link

gijsroge commented May 31, 2018

Sounds like a great way to optimize performance, but i'm very curious if this will serve actual content pre-rendered, or just some sort of placeholder skeleton?

Thanks for making this!

@gijsroge gijsroge changed the title What do you mean by "Meaningful content". Question: What do you mean by "Meaningful content". May 31, 2018
@developit
Copy link
Collaborator

developit commented May 31, 2018

Good question! It's actually entirely up to you. If your app does its entire initial rendering synchronously, you'll get that as the pre-rendered HTML. In a lot of cases, it would be more common to end up with a pre-rendered "App Shell", since data loading is generally not included when doing the simplest form of prerendering.

However, this is where prerender-loader gives you control over what happens: if you point it at an async function (like in the second String Prerendering example), you get to decide what to return and how long to wait for data.

Here's an example to illustrate:

<!-- src/index.html -->
<body>
  {{prerender:custom-prerender.js}}
</body>
// custom-prerender.js
import 'unfetch/polyfill';
import MyApp from './components/app';
import renderToString from 'preact-render-to-string';

export default async function prerenderWithData(params) {
  let res = await fetch('https://api.example.com/items.json');
  let items = await res.json();
  // now we have data, so we can render something meaningful:
  return renderToString(<MyApp items={items} />)
}

Note: params gets populated with whatever is passed to prerender-loader's params option


Side note: hydration

In the above example, we're prerendering using "items" data, but that data isn't available when the client code boots up in our browser. We can fix that too:

export default async function prerenderWithData() {
  let items = await (await fetch('https://api.example.com/items.json')).json();
  let script = document.createElement('script');
  script.textContent = `window.DATA = ${JSON.stringify(items)}`;
  document.body.appendChild(script);
  return renderToString(<MyApp items={items} />)
}

// now all we have to do is add a check in our MyApp component (or wherever "items" was being used) for window.DATA:
const MyApp = ({ items = window.DATA }) => (
  <ul>{items.map( item => <li>{item}</li> )}</ul>
)

@developit developit added the question Further information is requested label May 31, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

2 participants