Layouts
A layout wraps the pages in its directory and in nested directories. It is a Gem element marked with
@layout, and it renders <gemkit-outlet> where the child route appears.
src/pages/
_layout.ts root layout
index.ts /
blog/
_layout.ts wraps /blog, /blog/hello, ...
index.ts /blog
[slug].ts /blog/:slugDefine a layout
// src/pages/blog/_layout.ts
@layout()
export default class BlogLayout extends GemElement {
@template()
#content = () =>
html`
<aside>Categories</aside>
<article><gemkit-outlet></gemkit-outlet></article>
`;
}The root layout is src/pages/_layout.ts. It wraps every page, including the error page. A layout has no
URL of its own; it is matched by the directory it is in.
Nested layouts are kept when navigating between pages under the same layout. The root layout stays for the whole session unless the language changes, and a nested layout stays while its params don't change. This is useful for sidebars, tabs and other UI that should not be recreated on every navigation.
Layout data
A layout can load data like a page:
// src/pages/blog/_layout.ts
@layout({
load: () => fetch('/api/categories').then((res) => res.json()),
})
export default class BlogLayout extends GemElement {
@property data?: { name: string }[];
@template()
#content = () =>
html`
<aside>${this.data?.map(({ name }) => html`<a>${name}</a>`)}</aside>
<article><gemkit-outlet></gemkit-outlet></article>
`;
}The context is the same as for pages, { params, data }. params only contains the segments of the layout
directory, not the child route part. For example in src/pages/users/[id]/_layout.ts, params is
{ id } for any page under /users/:id.
The result is passed to the layout element as data. It can be a JSON value; the same rules as page
load apply.
When navigating between child routes, the layout data is reused as long as its params are unchanged. After a form submission it is loaded again, because the request may have changed the state it depends on, such as the current user.
A layout can also have a sibling _layout.server.ts, whose load result is passed to load as data.
The load: a layout load does not run for form actions and server elements, and on
client navigation it runs in parallel with the page load.
Meta
Layouts support meta, merged with the page meta. Inner routes override the same key:
@layout({
meta: { 'og:site_name': 'My Site' },
})Errors
When a page or layout load throws, the
Root layout and <gemkit-outlet>
The root layout is optional. Without it, pages are rendered directly in the root outlet. With it, the
layout's template is rendered first, and <gemkit-outlet> renders the matched child layout or page.
Only render <gemkit-outlet> once in a layout. It finds the routes of its owning layout by looking at its
parent element.
