React Router
React Router is the most popular routing solution in the React ecosystem and has evolved into a full-stack framework. React Router 7 is built on Vite, providing a modern development experience and supporting multiple rendering modes such as server-side rendering and static generation, enabling you to build high-performance full-stack Web applications.
Note:
Pages currently supports React Router version 7+ and full-stack deployment.
Core Features
Full-stack framework: Upgraded from a simple routing library to a full-stack framework, supporting integration of front-end and back-end development.
Multiple rendering modes: Supports SSR (server-side rendering), SSG (static generation), SPA (single-page application), and other rendering modes, flexibly adapting to different scenarios.
Nested routes: A powerful nested routing system that supports layout nesting and parallel data loading.
Data loading: Built-in data loading mechanism (loader) and data modification (action) to simplify data access and form processing.
Type-safe routing: Native TypeScript support with full type inference and route type safety.
File-based routing: Supports routing agreement based on file system to simplify routing configuration.
Quick Start
Start deploying a React Router project on EdgeOne Pages:
Import a React Router project from a Git repository
Select the React Router template from the Pages template library
Deploy a local project using the @edgeone/react-router framework adapter
Learn about React Router deployment performance on Pages, you can click the example template below:
Support for React Router in Pages
The following table shows the key characteristics of React Router that Pages currently supports. The platform will support additional features as soon as possible, but experimental features may not yet be completely stable.
React Router Features | Support Status |
Server-Side Rendering (SSR) | ✅ |
Static Site Generation (SSG) | ✅ |
Single Page Application (SPA) | ✅ |
Route Loaders | ✅ |
Route Actions | ✅ |
Nested Routes | ✅ |
File-based Routing | ✅ |
Streaming | ✅ |
Experimental features | Partially supported |
Deploying a React Router Project in Pages
@edgeone/react-router is a Vite plug-in that automatically adapts React Router v7 apps to the Pages platform, working with the Pages scaffolding tool to deploy local React Router projects.
Package and deploy the project to the Pages platform. The main features of @edgeone/react-router are as follows:
Automatic adaptation: Convert React Router v7 applications to an executable format for the Pages platform.
Multi-mode support: Supports SSR, SPA, pre-rendering, and other rendering modes.
Resource optimization: Automatic processing and packaging of static resources.
To deploy a React Router project in Pages, follow the steps below.
1. Installing an Adapter
npm install @edgeone/react-router
2. Configure Vite
In vite.config.ts, introduce and use edgeoneAdapter:
import { reactRouter } from "@react-router/dev/vite";import { defineConfig } from "vite";import { edgeoneAdapter } from "@edgeone/react-router";export default defineConfig({plugins: [reactRouter(),edgeoneAdapter() // add EdgeOne adapter],});
3. Deploying a Project
Git Connection Deployment
After integrating the adapter, you can submit the project to platforms such as GitHub or GitLab, and use our Git Connection Deployment.
CLI Deployment
You can also install the scaffolding tool for Pages. For detailed installation and usage, refer to EdgeOne CLI. Once configured, use the `edgeone pages deploy` command to deploy the project. During deployment, the CLI will first automatically build the project, then upload and publish the build artifacts.
Note:
EdgeOne CLI version requirement ≥ 1.2.0. Please first check the version before deployment to avoid deployment failure.
Server-Side Rendering (SSR)
Server-side rendering allows you to render webpages on servers dynamically. Every time users initiate requests, the server retrieves data and generates HTML in real time, improving SEO and the first-screen loading experience.
In React Router, data can be obtained through the loader function on the server:
// routes/post.tsximport type { Route } from "./+types/post";export async function loader({ params }: Route.LoaderArgs) {const post = await fetchPost(params.id);return { post };}export default function Post({ loaderData }: Route.ComponentProps) {return (<article><h1>{loaderData.post.title}</h1><div>{loaderData.post.content}</div></article>);}
Default build settings are as follows:
Build command:
npm run buildOutput directory:
build
Static Site Generation (SSG)
React Router supports pre-rendering static pages during build. By configuring the
prerender option, you can generate specified routes as static HTML.
Configure in
react-router.config.ts:import type { Config } from "@react-router/dev/config";export default {async prerender() {return ["/","/about","/blog/post-1","/blog/post-2",];},} satisfies Config;
can also dynamically generate pre-rendered routes:
export default {async prerender() {const posts = await fetchAllPosts();return ["/",...posts.map(post => `/blog/${post.slug}`)];},} satisfies Config;
Default build settings are as follows:
Build command:
npm run buildOutput directory:
build/client
Single-Page Application (SPA) Mode
If server-side functionality is not required, you can configure React Router in pure SPA mode. Set in
react-router.config.ts:import type { Config } from "@react-router/dev/config";export default {ssr: false,} satisfies Config;
Default build settings are as follows:
Build command:
npm run buildOutput directory:
build/client
Streaming Rendering
React Router supports streaming rendering through React 18's Suspense. Page content can be gradually transmitted from the server to the client without waiting for all data to load.
import { Suspense } from "react";import { Await } from "react-router";export async function loader() {// Return a Promise without waitingconst postsPromise = fetchPosts();const weatherPromise = fetchWeather();return {posts: postsPromise,weather: weatherPromise,};}export default function Dashboard({ loaderData }) {return (<div><Suspense fallback={<p>Loading posts...</p>}><Await resolve={loaderData.posts}>{(posts) => <PostList posts={posts} />}</Await></Suspense><Suspense fallback={<p>Loading weather...</p>}><Await resolve={loaderData.weather}>{(weather) => <Weather data={weather} />}</Await></Suspense></div>);}
More Resources
