File-based routing

Add about and news pages to the home page created in Getting started. minista determines URLs from file names and the directory structure in src/pages/.

This guide assumes a configuration with pluginSsg(), which is required for static HTML output.

Table of Contents

Add a page

Create src/pages/about.tsx and export a React component as the default export. Start the development server and open /about.

src/pages/about.tsx
import type { Metadata, PageProps } from "minista/types"

export const metadata: Metadata = { title: "About us" }

export default function About({ title }: PageProps) {
  return <h1>{title}</h1>
}

metadata is data passed to pages and layouts. Use Metadata to type-check its fields and PageProps to type-check the props received by the page. This example receives the metadata's title through props and displays it as a heading. See Layouts to reflect the title in the HTML head.

Nested pages

Create news/ and add index.tsx and hello.tsx inside it. Each becomes a page by writing a component just like the home page.

Project structure
src/pages/
├── index.tsx
├── about.tsx
└── news/
    ├── index.tsx
    └── hello.tsx

Running npm run build produces the following structure.

Build output
dist/
├── index.html
├── about.html
└── news/
    ├── index.html
    └── hello.html
Page fileDevelopment URLBuild output
src/pages/index.tsx/dist/index.html
src/pages/about.tsx/aboutdist/about.html
src/pages/news/index.tsx/news/dist/news/index.html
src/pages/news/hello.tsx/news/hellodist/news/hello.html

Whether extensionless URLs work after deployment depends on the host's configuration. If the host serves directory indexes, use a structure such as about/index.tsx.

Use regular a elements to navigate between pages. No dedicated router or link component is needed.

src/pages/index.tsx
import type { Metadata, PageProps } from "minista/types"

export const metadata: Metadata = { title: "My Site" }

export default function Page({ title }: PageProps) {
  return (
    <>
      <h1>{title}</h1>
      <nav>
        <a href="/about">About us</a>
        <a href="/news/">News</a>
      </nav>
    </>
  )
}

When publishing to a subdirectory with base, add the deployment path to page links as well. See Build and deploy for details.

Draft pages

Set draft: true for pages still in progress. They appear during development and are excluded from production builds.

src/pages/news/hello.tsx
import type { Metadata, PageProps } from "minista/types"

export const metadata: Metadata = {
  title: "News in progress",
  draft: true,
}

export default function Article({ title }: PageProps) {
  return <h1>{title}</h1>
}

Page file rules

Pages use .jsx, .tsx, .md, and .mdx. Place shared elements and data files outside page discovery, such as in src/components/ or src/data/.

Do not create files that resolve to the same URL. For example, about.tsx and about.mdx conflict. Check the page structure with npx minista check.

See Page generation from APIs for creating multiple pages from API data.

Next, Markdown and MDX adds another way to write content.