Skip to main content
Framework

Routes

Root.js uses file-based routing. Each .tsx file in routes/ is a page, and its path sets the URL. Square brackets mark URL params, and ... marks a catch-all param that matches several path segments (double brackets make it optional).

Route Matching URL(s)
@/routes/index.tsx /
@/routes/about.tsx /about
@/routes/blog/index.tsx /blog
@/routes/blog/[slug].tsx
  • /blog/foo
  • /blog/bar
@/routes/docs/[...slug].tsx
  • /docs/foo
  • /docs/foo/bar
@/routes/[[...page]].tsx
  • /
  • /foo
  • /foo/bar

Page

A route's default export is its page component. It's rendered to HTML on the server, and sends no JavaScript to the browser.

tsx
// @/routes/index.tsx

export default function Page() {
  return <h1>Hello, world!</h1>;
}

To pass data to the page, export getStaticProps() (for SSG) or handle() (for SSR) from the route.

getStaticProps()

When a route exports getStaticProps(), the props it returns are passed to the page. For routes with params, like [slug].tsx, the param values are passed in the context.

tsx
// @/routes/blog/[slug].tsx

import {GetStaticProps} from '@blinkk/root';

export default function Page(props) {
  return <h1>{props.post.title}</h1>;
}

export const getStaticProps: GetStaticProps = async (ctx) => {
  const post = await fetchPost(ctx.params.slug);
  return {props: {post}};
};

getStaticPaths()

To build a route with params as static HTML, Root.js needs to know every URL it serves. Export getStaticPaths() to return the list of params.

tsx
// @/routes/blog/[slug].tsx

import {GetStaticPaths} from '@blinkk/root';

export const getStaticPaths: GetStaticPaths = async () => {
  const slugs = await listPostSlugs();
  return {paths: slugs.map((slug) => ({params: {slug}}))};
};

handle()

To render a route on each request (SSR), export a handle() function. It works like an Express request handler: read the request, then call ctx.render() with the page's props.

tsx
// @/routes/hello.tsx

import {Handler, HandlerContext} from '@blinkk/root';

export default function Page(props) {
  return <h1>Hello, {props.name}!</h1>;
}

export const handle: Handler = async (req, res) => {
  const ctx = req.handlerContext as HandlerContext;
  const name = req.query.name || 'world';
  return ctx.render({name});
};

Use root build --ssr-only to build a site that only uses SSR, and root start to serve it.

404.tsx

To customize the "not found" page, add routes/404.tsx. It's rendered when no other route matches a request, and when a handle() function calls ctx.render404().

1
2
3
4
5
6
7
8
9
10
11
12
Breakpoint: