When building React applications, routing is like the GPS for your app: it tells users how to navigate and where to go within your interface. In React, one of the most popular ways to manage this navigation is by using React Router.
JSX is a syntax extension for JavaScript that looks like HTML, but under the hood, it's just a special way of writing JavaScript function calls. React Router provides two ways to define routes:
route objects (covered in the earlier reading)JSX and createRoutesFromElements (our focus here)Both approaches lead to the same outcome but have slightly different setups. For developers working with older React Router code bases or following certain examples from the official docs, the JSX approach can be more familiar.
Think of React Router as a well-trained guide dog who helps your user journey from page to page. Using JSX to define routes is especially handy when:
Below is an example folder structure you might see in a simple React project using JSX for routing. Notice that the filenames have no spaces or hyphens:
my_react_app/
package.json
src/
index.js
App.jsx
Home.jsx
TeamsIndex.jsx
TeamDetails.jsx
router.jsx
...
public/
index.html
...
In this structure:
App.jsx is our top-level application component.router.jsx can hold our router configuration.Home.jsx, TeamsIndex.jsx, and TeamDetails.jsx will be individual components for different routes.
Let's say we have a single route object that maps the path / to a Home component:
// Route object version
{
path: '/',
element: <Home />
}
To achieve the same result using JSX, we write:
<Route path='/' element={<Home />} />
This Route component is imported from react-router-dom. It takes two key props:
path: the URL pathelement: the component to be rendered when that path is accessed
In real life, routes often branch off into smaller sub-routes. Imagine your app is a big house; each room could be a route, and some rooms have closets or smaller compartments (nested routes). In JSX, you wrap the Route for the parent around its child routes, instead of using an array of children:
<Route path='teams'>
<Route index={true} element={<TeamsIndex />} />
<Route path=':teamId' element={<TeamDetails />} />
</Route>
This tells React Router:
/teams, show TeamsIndex.
/teams/anything (where anything is a team ID), show TeamDetails.
So how do we transform our JSX into an array of route objects that createBrowserRouter expects? The answer is createRoutesFromElements. It’s like a professional translator that takes your JSX syntax and converts it into a format the router can digest.
import {
createBrowserRouter,
RouterProvider,
Route,
createRoutesFromElements
} from 'react-router-dom';
const router = createBrowserRouter(
createRoutesFromElements(
<>
<Route path='/' element={<h1>Home Component</h1>} />
<Route path='teams'>
<Route index element={<h1>Teams Index Component</h1>} />
<Route path=':teamId' element={<h1>Team Details Component</h1>} />
</Route>
</>
)
);
function App() {
return <RouterProvider router={router} />;
}
export default App;
<></> is a React Fragment. We use it to group multiple Route elements without adding extra markup.
Imagine you want to build an app where the homepage is just "Welcome Home!", and you have a teams page showing either the "Teams Index" or details for a specific team.
Let’s walk through how you might set that up. (Feel free to follow along in your own project or create a fresh React app using create-react-app, Vite, or any setup you prefer.)
In src/:
Home.jsx:
import React from 'react';
function Home() {
return <h2>Welcome Home!</h2>;
}
export default Home;
TeamsIndex.jsx:
import React from 'react';
function TeamsIndex() {
return <h2>Here are the teams!</h2>;
}
export default TeamsIndex;
TeamDetails.jsx:
import React from 'react';
import { useParams } from 'react-router-dom';
function TeamDetails() {
const { teamId } = useParams();
return <h2>Details for Team: {teamId}</h2>;
}
export default TeamDetails;
router.jsx:
import React from 'react';
import {
createBrowserRouter,
createRoutesFromElements,
Route
} from 'react-router-dom';
import Home from './Home';
import TeamsIndex from './TeamsIndex';
import TeamDetails from './TeamDetails';
const router = createBrowserRouter(
createRoutesFromElements(
<>
<Route path='/' element={<Home />} />
<Route path='teams'>
<Route index element={<TeamsIndex />} />
<Route path=':teamId' element={<TeamDetails />} />
</Route>
</>
)
);
export default router;
App.jsx:
import React from 'react';
import { RouterProvider } from 'react-router-dom';
import router from './router';
function App() {
return <RouterProvider router={router} />;
}
export default App;
Now, when you run your app, visiting http://localhost:3000/ (or your local development port) should show Welcome Home!. Visiting http://localhost:3000/teams shows the "Here are the teams!" page. Going to http://localhost:3000/teams/76ers will render "Details for Team: 76ers" and so on.
Think of your app as a city and each route as a distinct neighborhood. Using JSX to declare routes is like giving each neighborhood a signpost that says "Head this way for the Home area" or "Enter here for the Teams area."
/products, /products/:productId, /cart, and /checkout.
/posts, /posts/:postId, /about, and /contact.
/profile/:userId, /messages, /settings, etc.
Wherever users need to switch views based on specific URLs, React Router helps keep the journey smooth and intuitive.
Practice solidifies knowledge! Here’s a quick exercise:
About.jsx in src/ with a simple message.router.jsx, add a Route for path='about' that renders your About component./about loads the new component.Link components (imported from react-router-dom) to navigate between pages from a navigation bar in App.jsx or another layout component.Route elements under it for a consistent header or footer across pages.
/teams/:teamId and something like /teams?teamId=76ers.
You've seen how to declare routes using JSX and how to use createRoutesFromElements to translate them into objects that createBrowserRouter understands. This approach is valuable for its readability, especially in codebases that prefer a more explicit, "JSX-first" style for everything related to UI.
Happy Routing!