Do you want to request a feature or report a bug?
What is the current behaviour?
If the current behaviour is a bug, please provide the steps to reproduce.
What is the expected behaviour?
If this is a feature request, what is motivation or use case for changing the behaviour?
Please mention other relevant information.
Hi,
Not really an issue but more clarification. I am trying to use preact-cli to create a working sample and want to introduce server side rendering to this.
I am a little unsure of what is expected of me from the Read.Me
In particular it mentions the following
PRPL pattern support for efficient loading
Zero-configuration pre-rendering / server-side rendering hydration
Should I be writing something that uses something like 'preact-render-to-string' or @developit own gist at
https://gist.github.com/developit/6e117d53f4f32b8f1e63bb43f5f6e937
Or is there something much easier I have to do to achieve this. I know there is a a cute example at
https://codepen.io/developit/pen/dYZqjE?editors=001
but this doesn't go into the rehydrate part on the client or answer a number of my questions.
The Read.Me mentions index.html and having multiple routes pre-rendered but again I am not sure what preact-cli does for me and what I am expected to do.
Once again. I know this is not an issue but am not sure where else to raise this.
Thanks
Mark
Hey Mark~!
Here's an example project you can look at that makes the most use of pre-rendering within a server.
This does as you suggest: It uses a catch-all route, preact-render-to-string, and the existing SSR bundle to render any incoming URL.
Taking this further, you can pre-render multiple urls (--prerenderUrls [file]) and then read from those files as new templates, optionally injecting any/all information as needed.
For example, you may have a /profile/:username route. You'll (probably) want to inject that username value into the outgoing response.
To do that, you'll want a custom template (--template [file]) that has something like this:
<% if (htmlWebpackPlugin.options.isProfile) { %>
<title>Profile: {INSERT_USERNAME}</title>
<!-- other profile-specific tags -->
<% } else { %>
<!-- defaults / normal values -->
<title><%= htmlWebpackPlugin.options.title %></title>
<% } %>
This is paired with your --prerenderUrls [file]:
[
{
"url": "/",
"title": "Home",
"...": "..."
}, {
"url": "/profile", // <~ HERE: single template
"isProfile": true, // <~ HERE: flag used within custom template
"...": "..."
}
]
That /profile file will be available at build/profile/index.html. You can read from it in your server & then inject the username as need be.
You can also add whatever keys & RegExp patterns you want~!
const index = fs.readFileSync('./build/index.html', 'utf8');
const profile = fs.readFileSync('./build/profile/index.html', 'utf8');
polka()
// ...
.get('/profile/:username', (req, res) => {
let { username } = req.params;
// make requests with username?
// whenever ready, send the response
res.end( profile.replace(/\{INSERT_USERNAME\}/g, username) );
})
// ...
Hope this helps~! I have this approach running in a few production apps.
Great answer Luke exactly what I was looking for. I won't close this for a few days in case I have a specific question once I try implementing.
You guys are making our lives too easy. 馃憤
Luke just one thing which isn't really related to your project but if I wanted to use Hot Module Replacement on that project how much work is involved? Have nodemon working in another project with a client and server but for some reason cannot get this project to work using it. I know this is nothing to do with Preact but if you had a quick fix I would be grateful.
You would need to attach the dev and hot middleware from webpack to your server, which both require that you grab your configs, create a compiler and then pass that to your middleware.
You also have to mutate the client config.
It's fairly involved and not easily done with the CLI.
I have a fairly big project releasing soon, I think this week, that will solve all of this for you!
Cool, I think I can wait a week or so. Have managed HMR in a client/server project I have but adding this SSR and my head is exploding. ;)
P.S Had been reading an article about your comments at
The Simplest webpack and express setup
but this stuff changes so quickly and the webpack config there appears old (over one year, ancient!!)
Any thoughts when you will be releasing @lukeed ? The excitement is building.
Haha, I'm still working on it! There's a pretty crap bug that would be awful to develop alongside. Will have a couple spare hours tonight to give it a whirl.
Did you manage to crush that bug @lukeed ?
@lukeed any spoiler on project name while I wait? Can just keep an eye on https://github.com/lukeed then
Any update @lukeed ? Don't want to sound like I'm hassling but a rough date would stop we waking in cold sweats.
Hey Mark 馃檲 Sorry I've dropped the ball on ya~! More bugs unfortunately, and I joined a company full-time, so that transition made it tough to find spare hours to bust this out.
It's definitely a massive project & I don't think it'll go unnoticed in the Preact ecosystem. A lot of people have this need right now, including myself, so you're definitely not alone!
Another kinda-sorta-hold-up is that I'd like it to build from & use the preact-cli core config handling. That way these two projects can co-exist nicely, and maybe even allow a dev to shift/upgrade from one to the other as the project evolves.
For now, I'd continue with the approach I mentioned above. I'm still using that approach in a number of projects & it scales (and performs) quite nicely. If you're in an environment that can use async/await, your life becomes even easier~!
Makes perfect sense Luke to have it baked in and understand the need to earn some money. I will progress with what I have then retrofit if need be once your baby is ready for a public view. To be honest I have been slack in waiting as my GraphQL backend certainly needs extra work. I will wait patiently from now on.
Oh oops. I meant to say that they were definitely going to be kept separate, just play nicely with each other.
Also meant to say that using the above method will make for an easy transition when using my project.
Requires that we expose an API - see:
https://github.com/developit/preact-cli/issues/515#issuecomment-379288347
Most helpful comment
Hey Mark~!
Here's an example project you can look at that makes the most use of pre-rendering within a server.
This does as you suggest: It uses a catch-all route,
preact-render-to-string, and the existing SSR bundle to render any incoming URL.Taking this further, you can pre-render multiple urls (
--prerenderUrls [file]) and then read from those files as new templates, optionally injecting any/all information as needed.For example, you may have a
/profile/:usernameroute. You'll (probably) want to inject thatusernamevalue into the outgoing response.To do that, you'll want a custom template (
--template [file]) that has something like this:This is paired with your
--prerenderUrls [file]:That
/profilefile will be available atbuild/profile/index.html. You can read from it in your server & then inject theusernameas need be.Hope this helps~! I have this approach running in a few production apps.