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

[SSR] Create server-side plugins for prerendering dynamic pages #19714

Open
kripod opened this issue Nov 22, 2019 · 1 comment

Comments

@kripod
Copy link
Member

@kripod kripod commented Nov 22, 2019

Summary

Gatsby makes it possible to create apps with authentication, using dynamically generated client-side routes. While most of the front-end optimizations rely upon the client, it feels like the last bit of performance could be squeezed by leveraging the capabilities of non-static web servers.

Basic example

Currently, pages can be built with or without static GraphQL queries. As an addition, I propose adding built-in support for serving dynamically generated pages stored inside '/src/pages', whether it exports a special property, e.g.:

// pages/profiles.jsx

// This may also just be called `routes` or `customRoutes`
export const routesOverride = [':id', '/users/:id'];

export default function ProfilesPage({ id }) {
  return <p>The currently viewed profile is: {id}</p>
}

The code above would remove profiles.jsx from the static page generation pipeline, serving as an opt-in method for creating dynamic paths, derived from the existent conventional file structure. For instance, the page above could be reached through one of the URLs below:

  • /profiles/:id
  • /users/:id

Dynamic segments start with a : as popularized by routers, and their parsed values are passed as props to the underlying component.

When no :-prefixed parameters are present, routesOverride could also serve the purpose of aliasing URLs of static pages, e.g.:

// pages/about.jsx

// The empty string is for keeping the '/about' route intact
export const routesOverride = ['', '/contact'];

export default function AboutPage() { /* ... */ }

As mentioned in the title, server-side plugins could be made to progressively enhance the rendering of dynamic pages. State shared between client and server could be transferred through cookies, possibly replacing localStorage for purposes it isn't meant to serve anyway. The main goal is to keep the coupling between client and server as low as possible, while providing on-demand SSR packages for popular frameworks like Express, Fastify, Koa and hapi.

While the concept of incorporating servers for a better user experience may seem to be out of the scope of this project at first, multiple tiers of adoption could be rolled out sequentially:

  1. Support aliasing statically generated pages
  2. Support opting in for dynamic page generation with :prefixed parameters
  3. Server-side plugins to reduce the script execution load of clients
    • A guide should be provided to serve dynamic pages from a static file server as a fallback to client-side rendering, e.g. for scenarios when the server gets overloaded

Motivation

Although @reach/router makes it possible to create custom routes, it feels like an escape hatch, diverging from Gatsby's opinionated directory structure and URL generation. Also, client-only routes must be served under a custom path prefix, making it unnatural to navigate between statically and dynamically generated pages.

@kripod

This comment has been minimized.

Copy link
Member Author

@kripod kripod commented Nov 26, 2019

An RFC about the topic has just been written for Next.js: zeit/next.js#9524

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
2 participants
You can’t perform that action at this time.