Catch-All Routes

We can use Route Strings and Route Functions to implement catch-all routes.

// product.page.route.js

// Match URLs that start with `/product/*`
// For example:
//  `/product/42/reviews`
//  `/product/1337/details`
//  `/product/2048/some/deeply/nested/path`
export default '/product/*`

The value of the catch-all parameter is available at pageContext.routeParams['*'].

To route all URLs to a single page:

// catch-all.page.route.js

export default '/*'

Route Functions enable all kinds of catch-all behavior.

// user.page.route.js

export default async (pageContext) => {
  const { url } = pageContext
  // Parse the URL
  const urlParts = url.slice(1).split('/')

  // Only URLs that start with `/user/*`
  if (urlParts[0] !== 'user') {
    return false
  }

  // Only URLs that start with `/user/:userId/*`
  const userId = urlParts[1]
  if (!userId) {
    return false
  }

  // Only if there is a user matching `userId`
  const user = await db.fetchUser(userId)
  if (!user) {
    return false
  }

  // Only URLs:
  // `/user/:userId/settings`
  // `/user/:userId/password-change`
  // `/user/:userId/profile`
  const selectedView = urlParts[2]
  if (!['settings', 'password-change', 'profile'].includes(selectedView)) {
    return false
  }

  return {
    // We add retrieved information to `pageContext.routeParams`
    routeParams: {
      userId,
      user,
      selectedView,
    }
  }
}