The routes directory is an intuitive yet unique way of organizing all of your static and dynamic content together in a single folder.


You can add a page to your app by creating a .js file that exports a default React component

export default function About() { return ( <main> <h1>About Us</h1> <p>...</p> </main> ) }

This page is rendered when you visit /about.

Pages are just regular React components with no magical named exports. You'll learn more about how to fetch and interact with data later on in this guide.

Dynamic Pages

You can create dynamic route segments by using a $ variable in your file or folder name:

import { useRoute } from 'firebolt' export default function Post() { const { slug } = useRoute().params return <div>Slug: {slug}</div> }

You can learn more about these and catch-all segments on the page.js reference.


Firebolt also supports nested layouts that maintain their state when switching between pages that share the same layout.

export default function Docs({ children }) { return ( <div> <nav>{/* shared navigation */}</nav> {children} </div> ) }
# Intro Let's get started...

In the example above, visiting /docs/intro will show the intro page nested inside the docs layout.

The root layout at routes/_layout.js is used to wrap your entire app with <html> and <body> tags.


As you might have noticed we also support MDX pages out of the box, allowing you to write your content with super powered markdown. Simply use the .mdx extension.

You can configure MDX with plugins to provide syntax highlighting or support github flavored markdown, anything you need.

You can also customize the components rendered by MDX with an MDXProvider

Static Files

The routes directory also serves all your static assets such as fonts and images. For example routes/robots.txt will be available at /robots.txt.

Virtual Files

For dynamic files that need to be generated on the fly you can create virtual assets by giving them a .js extension and handling the appropriate HTTP method

export function get(ctx) { const data = ` User-agent: * Disallow: ` return new Response(data, { headers: { 'Content-Type': 'text/plain', }, }) }

This gives you full control over all of your content and can be useful for many things including sitemap generation, image transformation and open graph image generators.

API Routes

You can use the same mechanism to create API endpoints, eg GET /api/users:

export function get(ctx) { return await ctx.db('users') }

As you'll see later on, unless your app explicitly needs to provide an API to its users, you won't even need these.


The routes folder is a simple yet powerful concept that allows you to keep your app organized, supporting essentially anything you might need.

When building components that need to be shared across multiple routes, you can place them outside of the routes directory in a components directory or similar, and pull them in as needed.

By the end of this guide you'll see that it's possible to build large complex SaaS applications that have little more than a routes and components directory. It's magic.