Page Setup

The following guide is for page creation in React Router v7's Framework Mode.

We recommend that you follow this guide with a fresh clone of our QUI Docs Template for the best experience.

Overview

  • We recommend creating pages with the remix-flat-routes Hybrid Routes strategy. The QUI Docs template is already configured for this.
    • You may also use the legacy flat routes convention from Remix v2.
    • For complete control, you can use React Router to create your own routes. You'll also need to provide a function to qui-docs for nav generation. Refer to the corresponding guide to learn more.
  • For your page to be picked up by the search index, it must be an mdx page.

If it's still a bit unclear, don't worry. Let's clarify things by walking through a few scenarios.

Config

QUI Docs is configured using a config file in the same directory as your app's vite.config.ts. Open the configuration file at qui-docs.config.ts, but don't edit it yet. The following is the default configuration that ships with the template:

// qui-docs.config.ts
import {QuiDocsConfig} from "@qui/mdx-vite"
export default {
appDirectory: "src",
navConfig: [
{
// The home page sidebar entry is defined via the reserved `_index` id.
id: "_index",
},
],
pageDirectory: "routes",
} satisfies QuiDocsConfig

Add a Page

Let's start by adding a few pages. Create a setup.mdx in the routes directory:

routes
setup.mdx

Populate your page with the following:

---
title: Setup
---
# {frontmatter.title}
This page contains setup instructions.

NOTE

We'll explain the # {frontmatter.title} syntax in the Markdown guide.

After adding this page, your sidebar should look like this:

In your application, click this route to navigate to the page. It should take you to /setup. Let's explore how this works.

Page URLs

Each page's URL is determined by its filepath relative to the routes directory. Nested paths are defined using folders that end with +. Here are a few examples:

file pathpage url
setup.mdx/setup
help+/troubleshooting.mdx/help/troubleshooting
guide+/content-creation+/overview.mdx/guide/content-creation/overview

Let's create a nested route now:

  • Create a folder in src/routes named help+.
  • Then create a file inside this folder called troubleshooting.mdx.
routes
help+
troubleshooting.mdx

And populate it with the following:

---
title: Troubleshooting
---
# {frontmatter.title}
This page contains common troubleshooting steps.

Your sidebar should now look something like this:

But now we have two issues:

  • The Setup page is one of the first pages that the user should visit, so it should probably appear before the Help page in the sidebar order.
  • The child page of the Help item isn't visible on first load.

To tackle these issues, we'll need to edit the navConfig.

For MDX pages, we define the title in the page's frontmatter. Our plugin extracts this title and incorporates it into the sidebar data. However, for path segments without associated pages (like folders), we can't do this because there is no MDX file to provide frontmatter.

We expose a navConfig property on the configuration object for this purpose.

Open the qui-docs.config.ts file from before.

// qui-docs.config.ts
import {QuiDocsConfig} from "@qui/mdx-vite"
export default {
appDirectory: "src",
navConfig: [
{
// the _index id is reserved for the home page. We'll touch on this later.
id: "_index",
},
],
pageDirectory: "routes",
} satisfies QuiDocsConfig

Let's address the issues. First, create an entry in the navConfig array for the setup page:

{
navConfig: [
// ...
{
id: "setup",
},
]
}

Your sidebar will immediately update to reflect the config changes. And now Setup is ordered properly!

  • The order of a sidebar item is determined by its array position in the navConfig.
  • Items defined in the navConfig are ordered before items that aren't defined.
    • This is why the order of the Setup item changed as soon as we added it to the config.

API

Refer to the API documentation to learn more about the available customization options.

Expanded State

Next, we'll add an entry to expand the Help folder. Folders in the sidebar are closed by default. To make the Help folder open automatically, set the expanded property to true.

{
navConfig: [
// ...
{
id: "setup",
},
{
expanded: true,
id: "help",
},
]
}

Now your sidebar should look something like this:

NOTE

If the site navigates to a nested route, the sidebar will automatically expand to show the route's item regardless of the route's navConfig entry.

We'll cover one more example to explain how the id property works for child items.

Let's add another page to our application.

  • Create a file: src/routes/help+/contact-us.mdx.
  • Populate it with the following:
---
title: Contact Us
---
# {frontmatter.title}
Contact us at [user@email.com](mailto:user@email.com).

Since routes without navConfig entries are ordered alphabetically, the Contact Us item appears before the Troubleshooting item in the sidebar. We can fix this by creating a few entries in the navConfig.

Since these routes are nested under the /help route, we'll need to add them to the /help item's children array:

{
navConfig: [
// ...
{
id: "setup",
},
{
expanded: true,
id: "help",
children: [
{
id: "troubleshooting",
},
{
id: "contact-us",
},
],
},
]
}

NOTE

For each id, we only need to match the path segment of the route at its current nesting level. The plugin walks the navConfig tree recursively to assemble the route and match against the MDX file.

Home Page

The home page is a reserved route and is defined by the _index id. The home page is located at routes/index.mdx, or routes/index/_index.mdx.

The source code for the QUI Docs Template home page is defined as follows:

---
hideBreadcrumbs: true
id: _index
title: Introduction
---
# {frontmatter.title}

Note the following about the home route:

  • The id must be defined for the home route in order for the page to show up in the sidebar.
  • Since the home page starts on the / route, there aren't any breadcrumbs to show. We set the hideBreadcrumbs: true in the page's frontmatter to disable them for this route.
    • This property can also be set on the page's navConfig entry.

React Page

You may also use a .tsx file to render a React page, but its content will not show up in the sidebar by default. To show React pages, you must add them to the sidebar via the navConfig. Note that these pages will not be picked up by the search indexer.

Advanced

Page and Folder

To define a route that is both a folder (expandable side nav entry) and a standalone page, follow these steps.

Let's assume that you're creating a page at /help, but you also have routes at /help/*.

  • Create a folder: routes/help+
  • Create a file: routes/help+/index.mdx
routes
help+
index.mdx

The contents of index.mdx will render at the /help route. The built-in side navigation will automatically account for this when you click on the link.

Custom Routes

React Router's Framework Mode supports manually-defined route definitions. When you define custom routes, our plugin doesn't automatically resolve the nav links from those files.

In the qui-docs config, you must supply your own routingStrategy to map each file to its corresponding site URL. This property takes a function that receives one argument:

  • filePath: the file's path relative to the pageDirectory.

The function must return a string[] representing individual path segments (seperated by /) to the file. Let's walk through a quick example.

Assume that we've defined the following routes:

src
routes
help
contact-us.mdx
troubleshooting.mdx
index.mdx
setup.mdx

Our routes.ts file would look like this:

// src/routes.ts
import {type RouteConfig, route, index, prefix} from "@react-router/dev/routes"
export default [
// home page
index("routes/index.mdx"),
route("setup", "routes/setup.mdx"),
...prefix("help", [
route("contact-us", "routes/help/contact-us.tsx"),
route("troubleshooting", "routes/help/troubleshooting.tsx"),
]),
] satisfies RouteConfig

In our QUI Docs config, we'd pass a function to the routingStrategy option as follows.

// qui-docs.config.ts
import {QuiDocsConfig} from "@qui/mdx-vite"
export default {
// ...
routingStrategy: (filePath: string) => {
// The home route is special and must return `[]`
if (filePath === "routes/index.mdx") {
return []
}
return filePath.split("/")
},
} satisfies QuiDocsConfig

The following table corresponds to the page input and expected path segments:

filePathexpected path segments
index.mdx[]
setup.mdx['setup']
help/contact-us.mdx['help', 'contact-us']
help/troubleshooting.mdx['help', 'troubleshooting']

Next Steps

This concludes our page setup guide. Refer to the NavConfig API to learn more about page and sidebar customization, or continue on to our Markdown guide to learn about content authoring.