Templates

Reusing common layouts across pages using templates.

Templates are a way to apply shared layouts to multiple pages, without having to duplicate any code.

Location

Templates are located in the templates folder at the root of your project source. If you are not already viewing the full project source, tap on Pages at the bottom of the sidebar, and select the Source view.

Project source

This will reveal the full project file tree:

components
pages
styles
templates
blog-index
blog-post
home
motif.json
tailwind.config.js

Structure

A template is a JSX component that receives, among others, a children property, holding the content of the page to which the template is applied. In addition, a meta variable can be defined, holding information about the template, such as its display name. Here is a rudimentary template, that wraps a page in a div with a padding and a lime background color:

export const meta = {
  name: "Blog",
}

export const Template = ({ children }) => {
  return <div className="p-8 bg-lime-100">
      {children}
    </div>
}

export default (props) => <Template {...props} />

The full ES module syntax is supported, so we can import components from other pages, use JavaScript logic to define variables and hold state, and so on:

export const meta = {
  name: "Blog",
}

import { Navbar } from "@components/navbar"

export const Template = ({ children }) => {
  return <div>
      <Navbar />
      <div className="p-8 bg-lime-100">
        {children}
      </div>
    </div>
}

export default (props) => <Template {...props} />

To learn more about layouts, make sure to read the Layouts article.

Other template properties

In addition to children, the template is served other properties that allow you to customize the behavior depending on the page that it is being applied to.

export const Template = ({
    filename,
    path,
    meta,
    files,
    children
  }) => {
  console.log("Page filename:", filename)
  console.log("Page path:", path)
  console.log("Page meta:", JSON.stringify(meta))
  console.log("Project files:", JSON.stringify(files))
  // ...
}
  • filename: the name of the file to which the template is being applied.
  • path: its full path as it appears when published, e.g. /blog/post-1.
  • meta: the page metadata.
  • files: the public pages file tree, e.g. to build an index of all published pages.

For instance, you may want to display the page title and publication date of your blog posts in a coherent way across your pages. You can achieve that by setting page metadata for each post, e.g.:

---
title: My first blog post
date: 2022-02-21
---

and then access the values in your template via the meta property:

export const Template = ({ meta, children }) => {
  <div>
    <h1>{meta.title}</h1>
    <h2>{new Date(meta.date).toDateString()}</h1>
    <div>{children}</div>
  </div>
}

Read more about this in the metadata article →

Applying a template

In order to apply a template to a page, open the document sidebar (by hitting the document icon next to the Share button), and select the template via the dropdown.

Choose template

Alternatively, head over to the motif.json configuration file (hit and type motif.json). Under the templates keys, you can create rules mapping page paths to templates. This allows you to say things such as "all pages in the blog folder should use the blog template", without having to explicitly select the template for each page.

{
  "templates": {
    "**/*": "main",
    "/blog/*": "blog",
    "about": "about",
  },

Read more about these rules in the Motif configuration article.