preactvercelpreact-router

Multiple preact-router routes rendered at the same time in SSR (on Vercel)


If you go to my Preact app on https://startupguide.vercel.app/ and click “Name Generator”, you will see only the Name Generator form (as it should be). But if you go to https://startupguide.vercel.app/namegenerator and refresh the page (to get SSR page), you see first the Name Generator form, AND the Start page underneath(!).

This is how I have set up my Preact routes:

import { Router } from 'preact-router'

import Start from './pages/Start'
import NameGenerator from './pages/NameGenerator'

const App = ({ prop }) => {
  return (
    <Router>
      <Start path='/' />
      <NameGenerator path='/namegenerator' />
      <NameGenerator path='/namegenerator/:word1' />
      <NameGenerator path='/namegenerator/:word1/:word2' />
    </Router>
  )
}
export default App

What could be the problem?


Solution

  • The /namegenerator page isn't actually being server-rendered. If you disable JavaScript and load the page, you'll see that it's just the homepage content. This causes an SSR mismatch, which breaks hydration.

    To fix this, you can prerender the namegenerator page by creating a prerender-urls.json file:

    [
      {
        "url": "/",
        "title": "Amazing Startup Guide"
      },
      {
        "url": "/namegenerator",
        "title": "Name Generator – Amazing Startup Guide"
      }
    ]
    

    Then update your package.json "build" script to pass that file as --prerenderUrls:

    "scripts": {
      "build": "preact build --prerenderUrls ./prerender-urls.json",
      ...
    }
    

    Pre-rendering docs are here: https://preactjs.com/cli/pre-rendering/#multiple-urls-and-custom-data