Compile-Time Data in LWR on Node.js
After you understand the basics about templating and layouts with LWR, you can use the various data provided by LWR for more complex scenarios. The place to start is with context objects.
Understand Context Objects
LWR uses a route’s templates and context to render the response for a page request.
The context object that LWR passes into HTML and Nunjucks templates contains data from several locations. This data is merged into a single object in this order:
When it comes to context objects, Markdown templates are a little different from HTML and Nunjucks templates. Context isn’t passed into Markdown templates unless you use a route handler, which is a way of customizing the page response. “Route Handler Functions” in Server-Side Routing in LWR discusses this advanced topic.
Note
Global Data
From the file system, you can pass any static global context data into your app’s content and layout templates. This data is available to all HTML or Nunjucks templates within your application. It is not available to component HTML templates, however.
1src/
2 └── data/ // global template context data
3 ├── site/
4 │ └── navbar.json
5 └── global.json1// $rootDir/src/data/global.json
2{
3 "siteTitle": "LWR Docs"
4}1// $rootDir/src/data/site/navbar.json
2[
3 {
4 "id": "guide",
5 "name": "Guide",
6 "url": "/guide/introduction"
7 },
8 {
9 "id": "recipes",
10 "name": "Recipes",
11 "url": "/recipes"
12 }
13]This global data is then added to the context.
1// context object
2{
3 "global": {
4 "siteTitle": "LWR Docs"
5 },
6 "site": {
7 "navbar": [
8 {
9 "id": "guide",
10 "name": "Guide",
11 "url": "/guide/introduction"
12 },
13 {
14 "id": "recipes",
15 "name": "Recipes",
16 "url": "/recipes"
17 }
18 ]
19 }
20}Front Matter
LWR reads any front matter out of a template and adds it to the context object. Front matter values are local to the template.
LWR uses the gray-matter parser to process front matter. This allows you to use YAML, JSON, TOML, or CoffeeScript to format front matter, or you can even set custom delimiters. The following is a YAML front matter example:
1---
2custom: 9000
3someText: Good to meet you
4immutable: false
5layoutTemplate: $layoutsDir/main_layout.njk
6---
7
8{# $rootDir/src/content/home.njk #}
9<p>{{someText}}</p>
10<p>{{custom}}</p>
11It is now {{ now | date('dddd, MMMM Do YYYY, h:mm:ss a') }}1---
2custom: 9000
3someText: Good to meet you
4immutable: false
5layoutTemplate: $layoutsDir/main_layout.njk
6---
7
8{# $rootDir/src/content/home.njk #}
9<p>{{someText}}</p>
10<p>{{custom}}</p>
11It is now {{ now | date('dddd, MMMM Do YYYY, h:mm:ss a') }}LWR has predefined the following front matter variables:
| Variable | Supported Template Languages | Notes |
|---|---|---|
layoutTemplate | HTML, Nunjucks, Markdown | Sets the layout template inside a content template. This value is overridden by the layoutTemplate set on the route. |
immutable | Nunjucks | Set this variable to false if the template contents are mutable; the default is true. Nunjucks templating allows mutable constructs to be embedded in a template’s content, for example, random and cycler. Due to this capability, templates that use these features must mark the template as mutable so LWR can modify the cacheability of the page response. |
Page Information
LWR can pass information about the page from the current route and request.
id:route.idtitle: set to the first defined value of the following:properties.titlefrom the route orviewParams.titlefrom the route handler- filename from
route.contentTemplate - “LWR App”
url: the request URL, relative to the origin
Example 1: When the current browser location is http://localhost:3000/ and the route is:
1// route in lwr.config.json
2{
3 "id": "home_page",
4 "path": "/",
5 "contentTemplate": "$contentDir/home.html",
6 "layoutTemplate": "$layoutsDir/main_layout.njk"
7}Then, the page information is:
1// context object
2{
3 "page": {
4 "id": "home_page",
5 "title": "home",
6 "url": "/"
7 }
8}Example 2: When the current browser location is http://localhost:3000/recipes?sort=desc and the route is:
1// route in lwr.config.json
2{
3 "id": "recipes",
4 "path": "/recipes",
5 "contentTemplate": "$contentDir/recipes.md",
6 "properties": {
7 "title": "Recipes Repository"
8 }
9}Then, the page information is:
1// context object
2{
3 "page": {
4 "id": "recipes",
5 "title": "Recipes Repository",
6 "url": "/recipes?sort=desc"
7 }
8}The object is accessible via the page context variable in the HTML/Nunjucks templates:
1{# $layoutsDir/layout.njk shows the page title and a logo on the home page #}
2<!DOCTYPE html>
3<html>
4 <head>
5 <title>{{page.title}}</title>
6 </head>
7 <body>
8 {% if page.id === 'home_page' %}
9 <img src="$assetsDir/images/logo.svg" alt="logo" />
10 {% endif %}{{ body | safe }}{{ lwr_resources | safe }}
11 </body>
12</html>Markdown Metadata
Markdown content templates produce context on their headings, which can be accessed from an HTML or Nunjucks layout template. Information on each heading starting with two or more # is included. For example, this Markdown:
1## Topic 1
2
3### Sub-Topic
4
5#### GrandchildProduces this context object:
1// context object
2{
3 "headings": [
4 {
5 "text": "Topic 1",
6 "slug": "topic-1"
7 },
8 {
9 "text": "Sub-Topic",
10 "slug": "sub-topic"
11 },
12 {
13 "text": "Grandchild",
14 "slug": "grandchild"
15 }
16 ]
17}The object is accessible via the headings context property in HTML/Nunjucks layout templates:
1{# $layoutsDir/partials/nav.njk shows a link for each heading #}
2<ul>
3 {% for mdHeading in headings %}
4 <li><a href="#{{mdHeading.slug}}">{{mdHeading.text}}</a></li>
5 {% endfor %}
6</ul>Static Route Properties
You can pass static context into HTML/Nunjucks templates from a route via its properties:
1// route with properties in lwr.config.json
2{
3 "id": "about",
4 "path": "/about",
5 "contentTemplate": "$contentDir/about.html",
6 "properties": {
7 "someText": "Lorem ipsum dolor sit amet"
8 }
9}1<!-- $contentDir/about.html shows the route property -->
2<h2>About</h2>
3<p>{{someText}}</p>Route Handlers
Context objects can optionally contain route handlers. Route handlers are functions that allow you to customize the page response for a route. “Route Handler Functions” in Server-Side Routing in LWR discusses this advanced topic.
LWR
LWR automatically passes two context object properties:
body: Available in layout templates, a string containing the rendered page content that is output from the route’scontentTemplateorrootComponent.lwr_resources: A string containing all the scripts required to run your application, such as the Lightning Web Component library and LWR client resources. If this string is excluded from the page response, embedded Lightning web components don’t render.- Note: The
lwr_resourcesproperty is optional. If you have purely static HTML content (no Lightning web components, module resolution, or other LWR features), you don’t require LWR resources in your layout. In the static site you created as your first project, themain_layout.njkfile doesn’t includelwr_resources.
- Note: The
Here are examples of HTML and Nunjucks layout templates that use both LWR properties:
HTML:
1<!-- $layoutsDir/main.html -->
2<!DOCTYPE html>
3<html>
4 <head></head>
5 <body>
6 <!-- triple braces prevents HTML escaping -->
7 {{{body}}} {{{lwr_resources}}}
8 </body>
9</html>Nunjucks:
1{# $layoutsDir/main.njk #}
2<!DOCTYPE html>
3<html>
4 <head></head>
5 <body>
6 {# the "safe" filter prevents HTML escaping #} {{ body | safe }}{{lwr_resources | safe }}
7 </body>
8</html>Developer Preview Feature