Server-Side Routing in LWR on Node.js
To set server-side routes for your app with LWR, use the lwr.config.json
project configuration file. Server-side routes can be specified in lwr.config.json
by providing either:
- a static path for each page
- a JavaScript file that defines a hook to dynamically generate server-side routes for pages at server startup (this is an advanced option)
Both static and dynamic server-side routes can also have route handler functions, which let you customize the page response at runtime.
Read on for details. We start with a basic static routing example.
Let’s add a page to our site and do some basic (and fast!) routing.
- Now that you’ve got your
StaticSite
project, make a copy of theabout.md
file. Rename the new fileexplore.md
and leave it in thecontent
directory. - Edit the
explore.md
file. Change the first line from# About LWR
to# Explore LWR
. Save the file. - Open the
main_layout.njk
file. On a new line, add<li><a href="/explore">Explore</a>
under theabout
line. Save the file. - Finally, open the
lwr.config.json
file. Copy the entire block of code forabout
, including the curly brackets, and paste it below theabout
block. Changeabout
toexplore
throughout, and don’t forget to add the comma after the closing bracket in theabout
block. Save the file. - If you're still in the
StaticSite
directory from when you first made your site, just typenpm run start
in the terminal to see your changes. Your updatedStaticSite
project runs at http://localhost:3000/, with a new Explore LWR page and a working Explore button.
If you get a "Port 3000 is already in use" error after running npm run start
, close any terminal tabs that run your site preview. Then, open a new terminal tab and run npm run start
.
What just happened is that you:
- created a Markdown page (
explore.md
) and gave it new heading text ("Explore LWR") - updated the site navigation in the Nunjucks layout (
main_layout.njk
) file to include a new Explore button - updated the JSON routing configuration file (
lwr.config.json
) to let LWR know how to route to the new page using a route- you gave an
id
for the page (Explore
) - you provided the
path
for the page (/explore
) - you provided a
contentTemplate
for the page (explore.md
) - you told LWR the
layoutTemplate
to use for the page; in this case, you usedmain_layout.njk
, which is the same as for other pages in this example, though that’s not required
- you gave an
You can set up routes to serve if a LWR encounters a 404
or 500
error during the bootstrap of a route. Error routes take a status
code value instead of a path
value.
This is an advanced topic.
Configuration hooks let you dynamically generate server-side routes for your application. On server startup, they update the configuration and global data for your app.
To set up a configuration hook, start by creating a hooks
section in your lwr.config.json
file. In there, add the filepath that points to the hook.
The following is an example of a configuration hook:
Dynamic server-side routes can use route handler functions to customize the page response at runtime.
This is an advanced topic.
Route handler functions are part of the LWR context object. They’re a server-side way to alter the current route and customize the page response at runtime. You can use route handler functions with both static and dynamic server-side routing.
Route handler functions, which are used in LWR's server-side routing, aren’t the same as route handler modules, which are used in client-side routing.
There are a couple of differences between configuration hooks and route handler functions that are worth noting:
- A configuration hook is called once on server startup, while a route handler is triggered with each incoming page request.
- A configuration hook applies to your entire app, whereas each route handler applies only to its specified path.
You provide the path to a route handler function in lwr.config.json
, like this:
A route handler function follows this syntax. For more information about syntax and properties of RouteHandlerFunction
and the RouteHandlerViewReponse
that it returns, see the Server-Side Routing Reference.
Things to note:
- Cache size. All the
ViewDefinitionResponse.viewParams
are added to the cache key for a page view response. To control cache size, monitor the number of items added. - Static route properties. The
ViewDefinitionResponse.viewParams
replace the static route properties, so if the static route properties are needed, you must merge them into theviewParams
in the route handler function. - Markdown. The dynamic
ViewDefinitionResponse.viewParams
are available in Markdown content templates. This is notable because in general context isn't passed into Markdown templates, unless you use a custom route handler. - View. LWR merges the
ViewDefinitionResponse.view
with theid
andbootstrap
values from the current route. - Time-to-live. The
CacheResponse.ttl
is a number, in seconds, or a time string to use as themax-age
on theCache-Control
header. - Supported languages. You can use both TypeScript and JavaScript to create your route handler.
The following is an example of using a route handler function to customize a page response. The LWR server constructs the page response from this function.
The following is an example of using a route handler function to completely override a page response. The LWR server constructs the page response from this function.