Skip to content

Gatsby Pages and Routing — File-Based Routing in Gatsby

DodaTech Updated 2026-06-28 4 min read

Learn how Gatsby creates routes from page files, how to structure pages, and how to create dynamic pages programmatically using Gatsby's file-based routing.

In this lesson, you'll understand how Gatsby maps files to routes, how to organize page components, and when to use programmatic page creation.

What You'll Learn

How file-based routing works, how to create nested routes with directories, how to use the Link component, and how to create pages programmatically from data.

Why It Matters

Gatsby's routing determines how users navigate your site. Understanding both file-based and programmatic page creation lets you build any site structure.

Real-World Use

The DodaTech documentation site uses Gatsby pages for the main docs and programmatic page creation for each product version, generating hundreds of versioned pages automatically.

flowchart LR
    A[src/pages/] --> B[index.js /]
    A --> C[about.js /about]
    A --> D[blog/]
    D --> E[blog/index.js /blog]
    D --> F[blog/post.js /blog/post]
    G[gatsby-node.js] --> H[Programmatic Pages]
    H --> I[/products/:slug]
    H --> J[/blog/:slug]
    style A fill:#639,color:#fff
    style G fill:#4a148c,color:#fff

File-Based Routing

Every .js file in src/pages/ becomes a route:

src/pages/
├── index.js       → /
├── about.js       → /about
├── contact.js     → /contact
├── blog/
│   ├── index.js   → /blog
│   └── post.js    → /blog/post
// src/pages/about.js
import React from 'react';

export default function AboutPage() {
  return (
    <div>
      <h1>About Us</h1>
      <p>This page lives at /about.</p>
    </div>
  );
}

Output: The route /about renders the AboutPage component. The filename determines the URL path.

Linking Between Pages

Use Gatsby's Link component for client-side navigation:

import { Link } from 'gatsby';
import React from 'react';

export default function HomePage() {
  return (
    <div>
      <h1>Home</h1>
      <nav>
        <Link to="/about/">About</Link>
        <Link to="/contact/">Contact</Link>
        <Link to="/blog/">Blog</Link>
      </nav>
    </div>
  );
}

Output: Links use client-side navigation without page reload. Gatsby prefetches linked pages in the background.

Dynamic Routes with Colons

Gatsby supports client-only routes for authenticated sections:

// src/pages/app/[...].js
import { Router } from '@reach/router';
import React from 'react';

const Dashboard = () => <h1>Dashboard</h1>;
const Settings = () => <h1>Settings</h1>;
const Profile = () => <h1>Profile</h1>;

export default function App() {
  return (
    <Router basepath="/app">
      <Dashboard path="/" />
      <Settings path="/settings" />
      <Profile path="/profile" />
    </Router>
  );
}

Output: Routes under /app/ are handled client-side, useful for authenticated sections that shouldn't be pre-rendered.

404 Pages

Create a custom 404 page:

// src/pages/404.js
import React from 'react';
import { Link } from 'gatsby';

export default function NotFound() {
  return (
    <div>
      <h1>Page not found</h1>
      <p>The page you're looking for doesn't exist.</p>
      <Link to="/">Go home</Link>
    </div>
  );
}

Output: Gatsby automatically uses 404.js as the 404 page. In development, it's visible at /404/. In production, it becomes 404.html.

Common Mistakes

  1. Using <a> instead of <Link>: Regular <a> tags cause full page reloads. Always use Gatsby's <Link> for internal navigation.
  2. Forgetting trailing slashes in to: Gatsby expects trailing slashes by default. Use to="/about/" not to="/about".
  3. Not creating a 404 page: Without 404.js, users get the default 404 page, which may not match your site design.
  4. Putting components in src/pages/ that aren't routes: Every file in pages/ becomes a route. Put non-route components in src/components/.
  5. Capitalization mismatches: Gatsby routes are case-sensitive. /About and /about are different routes.

Practice Questions

  1. What URL does src/pages/blog/post.js become? Answer: /blog/post. The directory structure maps directly to the URL path.

  2. What component does Gatsby's Link use internally? Answer: @reach/router's Link component. Gatsby wraps it with prefetching behavior.

  3. How do you create a client-only route in Gatsby? Answer: Create a file with [...] in the name (e.g., app/[...].js) and use @reach/router inside it.

  4. Where should non-page components be placed? Answer: In src/components/ or other directories outside src/pages/ to prevent unintended route creation.

Challenge

Create a site with nested routes: /, /products, /products/:slug, /about. Use both file-based routing for static pages and a client-only route for the dynamic product detail page.

Mini Project

Build a multi-page marketing site with Home, About, Features, Pricing, and Contact pages. Use Gatsby's Link for navigation, include a 404 page, and add a header component shared across all pages.

FAQ

Does Gatsby support React Router?

: Gatsby uses @reach/router by default, not React Router. @reach/router is included with Gatsby and has a similar API.

Can I create pages with URL parameters?

: Yes, using client-only routes with [...] filenames or programmatic page creation in gatsby-<a href="/backend/nodejs/">Node.js</a>.

Does Gatsby support hash routing?

: Not natively. Gatsby uses the History API for clean URLs. Use a custom router for hash-based navigation.

How do I create redirects in Gatsby?

: Use the gatsby-plugin-client-side-redirect plugin or configure redirects in gatsby-node.js with the createRedirect action.

What's Next

Learn about Gatsby Link Component and Navigation for deeper coverage of navigation patterns and prefetching.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro