Redwood v0.26: The Prerender Release 🚀

Update: the latest release is v0.26.2

This release introduces the new Prerender feature, which is the culmination of months of work by many individuals across the community. Prerender in Redwood is opt-in (simply add a prop to a Route!) with built-in support that “just works” — it’s fully compatible with other Redwood features like Cells. This is the first new feature from the Redwood at Scale initiative, which will bring many future improvements to application performance.

We think you’re going to like it :rocket:

:warning: This release contains Breaking Changes and requires code modifications. See the “Breaking” and “How to Upgrade” sections for more information.

v0.26.0 Highlights :tada:

:zap: Redwood Prerender

Both @dac09 and @peterp carried this one to the finish line. Well done, you two!

Although prerendering is as easy as adding a prerender prop to a Route, there’s more you can do and need to know:

  • Redwood Prerender Doc: how to, helpers, and specific considerations
  • For reference, you’ll want to understand how Redwood is now automatically handling App.js mounting to the DOM. And for complex cases, you might need to customize index.js. Take a look at the Custom Index Doc
  • For a full walk-through of Redwood Prerender, including discussion and Q&A, watch this YouTube Video from the most recent Meetup

Ready to get started?
All new Redwood projects are ready for prerendering once they’re installed! 'Cause that’s the Redwood way :evergreen_tree:

If you’re upgrading your project, start with the “Manual Code Modifications” section below before you set up prerender on your Routes.

:closed_lock_with_key: Nhost Auth Provider

The fine folks at Nhost have added a Redwood Auth provider. Check it out!

Changed

Added

  • Prerender: Render landing/marketing/static pages + Private page whileLoading #1641 by @dac09 :tada:
  • Prerender: image support #1721 by @dac09
  • Prerender: Better messages when no routes marked with prerender #1821 by @dac09
  • Prerender: Hide entry.js | Add setup command to restore #1842 by @dac09 :warning:
  • Prerender: Changes for prerender release #1855 by @dac09
  • Auth: Nhost Auth 1.0 provider #1725 by @nunopato :tada:
  • CSS: Minify CSS in production builds #1697 by @dac09
  • Internal: Add Cypress Step6 Test #1780 by @wafuwafu13
  • Internal: New contributor workflow #1792 by @dac09
  • Internal: Add curly rule for blocks #1836 by @Krisztiaan
  • Docs: Docs: Update contributor workflow to yarn rwt link #1803 by @jtoar
  • Docs: Update CONTRIBUTING.md rwt link docs #1852 by @dac09
  • TS: Add types to Flash, clean up some logic #1824 by @Krisztiaan

Fixes

  • Prerender: Fixes to crwa template for prerender #1819 by @dac09
  • Prerender: Adds types for pageLoadingContext | Fix for pageLoader during prerender #1832 by @dac09
  • Prerender: replace instances of web/src/index.js with web/src/App.js #1857 by @thedavidprice
  • Prisma: use new ‘prisma’ package to replace ‘@prisma/cli’ #1800 by @thedavidprice
  • CLI: Passthrough error codes on cli failures #1791 by @dac09
  • CLI: Remove backticks #1826 by @adriatic
  • CLI: Fix dataMigrate command import error via babel register #1845 by @dac09
  • CLI: fix rw test command when run from dir other than root and upgrade execa #1846 by @thedavidprice
  • Storybook: Don’t open storybook when --open=false is given #1795 by @jvanbaarsen
  • Template: Lint the create-redwood-app template #1822 by @peterp
  • TS: Fix Router TS types #1823 by @Tobbe
  • Internal: E2E if path to project given, use the installed packages #1837 by @thedavidprice
  • Internal: webpack config use || instead of ?? #1881 by @Tobbe
  • Generators: Fixes generating scenarios for relations where the field name is different than the relation name #1848 by @cannikin
  • Tests: Run Teardown after each test #1818 by @jvanbaarsen

Breaking :warning:

To offer built-in Prerender support, Redwood now handles mounting the React <App /> to the DOM internally. This enhancement required breaking changes to the existing web/src/index.js.

  • in web/src/index.js, the React root element is now a component. References to the browser window, e.g. document. will throw an error
  • web/src/index.js has been renamed to web/src/App.js

To learn more about how Redwood is automatically handling mounting, see this Custom Web Index doc. For some applications with specific index.js requirements, this document provides customization instructions.


How to upgrade Redwood to the latest v0.26

:point_right: IMPORTANT: Skipping versions when upgrading is not recommended and will likely cause problems. Do read through all Release Notes between your current version and this latest version. Each minor release will likely require you to implement breaking change fixes and apply manual code modifications.

Manual Code Modifications

1. Rename web/src/index.js to web/src/App.js

2. In web/src/App.js, convert the React root element to a component named App

Any references to the browser window need to either be removed or wrapped in a conditional like isBrowser (see step 4 for more about the Prerender utils Redwood provides to make checking for these cases easier). For existing Redwood projects, this means at a minimum you’ll need to remove ReactDOM.render(...document.getElementbyID()...

-import ReactDOM from 'react-dom'

import { FatalErrorBoundary } from '@redwoodjs/web'
import { RedwoodApolloProvider } from '@redwoodjs/web/apollo'

import FatalErrorPage from 'src/pages/FatalErrorPage'
import Routes from 'src/Routes'

import './index.css'

-ReactDOM.render(
+ const App = () => (
  <FatalErrorBoundary page={FatalErrorPage}>
    <RedwoodApolloProvider>
      <Routes />
    </RedwoodApolloProvider>
  </FatalErrorBoundary>,
-  document.getElementById('redwood-app')
)

+ export default App

Depending on other custom implementations to your projects App.js, you may need to make additional changes or, in some cases, even create a custom web/src/index.js to handle Reacting mounting. If so, see the Custom Web Index doc

3. Update web/src/index.html to support prerender

This lets Redwood know where to place your pre-rendered HTML.

...

<body>
  <div id="redwood-app">
+    <%= prerenderPlaceholder %>
  </div>

...

4. Special Prerender Considerations

If you’re ready to take Prerender for a spin, now is the time to look through the Redwood Prerender Doc, especially the section “Prerender Utils”.

Sometimes you’ll need granular control over what gets prerendered. For example, if you’re using Netlify Identity, you can only initialize it on the browser. You’ll need to use the isBrowser helper in your web/src/App.js:

+ import { isBrowser } from '@redwoodjs/prerender/browserUtils'
...

+ if (isBrowser) {
  netlifyIdentity.init()
+ }

Don’t worry, we don’t expect you to know how to identify every case like this. You can check using the following debugging flow:

  1. First run yarn rw build web. If elements can’t run on Node.js, they’ll throw errors here, which will show you what needs specific handling.
  2. Once you can build successfully, then run yarn rw prerender --dry-run. You may get a lot of warnings, which is fine. Keep a lookout especially for error, which indicates other elements that require special handling.

Upgrade Packages

Run the following command within your App’s directory:

yarn rw upgrade

Need help or having trouble upgrading packages? See this forum topic for manual upgrade instructions and general upgrade help.


Redwood Releases on GitHub

You can see all Redwood release notes and version history on GitHub

9 Likes

@thedavid you provided the instructions for upgrading TO version v0.26 - what’s missing is FROM. Since I am already running v0.25.1, it is very likely that I am safely assuming that these instructions are fine for me.

2 Likes

Every release shows how to upgrade from the previous release only, hence the note!

2 Likes

Patch Release v0.26.1

We’ve released a patch that fixes an issue some developers were experiencing when using test scenarios:

Patch Release v0.26.2

We’ve released a patch that fixes a webpack error on Node.js v12:

Thanks for the great upgrade notes every time @thedavid!

Redwood is the easiest upgrade path I’ve encountered for a framework like this so far. Despite the fact lots is changing pre the 1.x release, I still haven’t run into any hiccups.

3 Likes

https://gph.is/g/4A1gWjO

4 Likes

Those dark paths are walked by the unlucky who precede you in upgrading x).

Got some points on Prerendering!

it bumps a warning:

Warning: Did not expect server HTML to contain the text node "
" in <div>.

And we can see a thread that seems to be related here: "Did not expect server HTML to contain the text node" due to whitespace in React 16 ¡ Issue #10879 ¡ facebook/react ¡ GitHub
Not sure yet what can fix it and not sure either it pressures for a quick fix.

What about React.Suspense?

I’ve just lost a couple of hours because an upgrade to react-i18n means the key react.wait in i18n configuration is deprecated and it’s recommended to move to react.useSuspense, which I did otherwise the entire app crashes:

const App = () => (
  <FatalErrorBoundary page={FatalErrorPage}>
    <RedwoodApolloProvider>
      <ThemeProvider theme={theme}>
        <Suspense fallback={'ha-Ha!'}>
          <Routes />
        </Suspense>
      </ThemeProvider>
    </RedwoodApolloProvider>
  </FatalErrorBoundary>
)

Is it going to work well with RW’s Prerender? With my tests on Slow 3G I don’t get the route’s whileLoading component, I only get the ha-Ha! from my Suspense comp. What’s the appropriate way to handle this?

We have an active issue for this #1887

1 Like

Thanks @noire.munich!

^^ looping in @danny

Thanks for this! I had to manually upgrade also from v0.25.1.

After doing the four manual code modifications above, it failed on rw build web. So I had to manually upgrade to the next release with yarn rw upgrade -t 0.26.0. After that, it stopped getting errors for yarn rw dev in the web component. So repeated this twice more to get to to v0.26.2.

1 Like