DEV Community

Cover image for Understanding Layout Components and React Router Outlet in React
Jack Pritom Soren
Jack Pritom Soren

Posted on

Understanding Layout Components and React Router Outlet in React

Maintaining reusable, effective layouts is crucial when developing modern online applications. The React Router's Outlet and layout components are essential tools for achieving this in React. These ideas aid in creating a scalable and user-friendly page structure. This blog article will explain how they function together and walk you through putting them into practice.

What are Layout Components?

React layout components are reusable parts that specify your application's skeleton or structure. Consistently placed headers, sidebars, footers, and navigation bars are examples of layout components. By centralizing these common structures, these components help you reduce duplication and improve the maintainability of your program.

Benefits of Layout Components

  • Reusability: You don’t need to rewrite your header, footer, or sidebar on every page.
  • Consistency: Provides a uniform look and feel across the entire application.
  • Separation of Concerns: Clearly separates the static layout from dynamic page content.

Here’s an example of a basic layout component:

// Layout.js
import React from 'react';
import Header from './Header';
import Footer from './Footer';

const Layout = ({ children }) => {
  return (
    <div>
      <Header />
      <main>{children}</main>
      <Footer />
    </div>
  );
};

export default Layout;
Enter fullscreen mode Exit fullscreen mode

In this example, the Layout component wraps the content of each page with a Header and Footer. The {children} prop is where the dynamic content will be rendered.

Understanding React Router

React Router is the go-to solution for managing navigation in React applications. It allows you to define routes for different pages and manage how users navigate between them. With React Router, you can also nest routes, which is useful for more complex layouts.

When working with layouts, React Router’s Outlet is especially important.

What is the Outlet in React Router?

The Outlet component is a placeholder in your layout where the matched child route components will be rendered. It’s particularly useful when you want different routes to share a common layout (e.g., admin dashboards, blog posts, etc.).

In simpler terms, if your application has a shared layout across multiple routes, Outlet ensures that the content of each route is dynamically injected into the layout.

Basic Example with Outlet:

// App.js
import { BrowserRouter as Router, Routes, Route } from 'react-router-dom';
import Layout from './components/Layout';
import Home from './pages/Home';
import About from './pages/About';
import Contact from './pages/Contact';

function App() {
  return (
    <Router>
      <Routes>
        <Route path="/" element={<Layout />}>
          <Route index element={<Home />} />
          <Route path="about" element={<About />} />
          <Route path="contact" element={<Contact />} />
        </Route>
      </Routes>
    </Router>
  );
}

export default App;
Enter fullscreen mode Exit fullscreen mode

In this example:

  • The Layout component will wrap the Home, About, and Contact pages.
  • Inside the Layout component, we use the Outlet component as a placeholder for the route-specific content.
// Layout.js
import { Outlet } from 'react-router-dom';

const Layout = () => {
  return (
    <div>
      <header>My App Header</header>
      <nav>Navigation Bar</nav>
      <main>
        <Outlet /> {/* Content specific to the route will be rendered here */}
      </main>
      <footer>My App Footer</footer>
    </div>
  );
};

export default Layout;
Enter fullscreen mode Exit fullscreen mode

Nested Routes with Outlet

The Outlet becomes even more powerful when you have nested routes. For instance, if you’re building a blog platform with posts under a /blog route, the layout might be the same for all blog-related pages (e.g., list of posts, post details), but the content inside will differ depending on the exact route.

// BlogLayout.js
import { Outlet } from 'react-router-dom';

const BlogLayout = () => {
  return (
    <div>
      <h1>Blog</h1>
      <nav>Blog Navigation</nav>
      <Outlet /> {/* Nested routes (list of posts or individual post) will be rendered here */}
    </div>
  );
};

export default BlogLayout;
Enter fullscreen mode Exit fullscreen mode

In the main routing structure:

// App.js
<Routes>
  <Route path="/" element={<Layout />}>
    <Route path="blog" element={<BlogLayout />}>
      <Route index element={<BlogList />} /> {/* List of blog posts */}
      <Route path=":postId" element={<BlogPost />} /> {/* Individual blog post */}
    </Route>
  </Route>
</Routes>
Enter fullscreen mode Exit fullscreen mode

Here, the BlogLayout ensures that the blog's navigation and title are consistent across all blog-related pages, while the specific content (BlogList or BlogPost) is rendered via the Outlet.

Benefits of Using Outlet with Layout Components

  1. Efficient Code Management: By creating a layout component with an Outlet, you can reuse the layout structure across multiple pages without code duplication.
  2. Clean Structure: Separating layouts from content makes the code more readable and maintainable.
  3. Easy Nested Routes: Outlet allows you to nest routes and manage complex routing structures effortlessly.

Feel free to check out the detailed coding demonstration in my video, where I walk through the process of setting up layout components and utilizing Outlet with React Router. You can watch the tutorial here:

Watch Now on YouTube!

Conclusion

In any React project, organizing your code to keep it modular, reusable, and efficient is crucial for long-term scalability. Layout components and the Outlet in React Router enable you to achieve this by providing a way to define consistent page structures while dynamically injecting route-specific content. Whether you're building a small blog or a large multi-page application, mastering these tools will help you create clean and scalable applications.

Happy coding!

Follow me on : Github Linkedin

Top comments (5)

Collapse
 
nhanne249 profile image
Nguyễn Ngô Vũ Nhân

If I want to use another js file to store the Route values ​​(path, element...) instead of listing each Route like your example, what should I do?
Is using map() possible?

Collapse
 
jps27cse profile image
Jack Pritom Soren

Just Create a separate JS file (e.g., routes.js):



const routes = [
  { path: '/', element: Home },
  { path: '/about', element: About },
  { path: '/contact', element: Contact   
 },
];


Enter fullscreen mode Exit fullscreen mode

Import and use routes in your main component (e.g., App.js):



function App() {
  return (
    <Router>
      <Routes>
        <Route path="/" element={<Layout />}>
          {routes.map((route) => (
            <Route key={route.path} {...route} />
          ))}
        </Route>
      </Routes>
    </Router>
  );
}


Enter fullscreen mode Exit fullscreen mode

If you have nested routes, you can structure your routes array accordingly.



const routes = [
  {
    path: '/blog',
    element: BlogLayout,
    children: [
      { path: '/', element: BlogList },
      { path: '/:postId', element: BlogPost },
    ],
  },
];



Enter fullscreen mode Exit fullscreen mode

Thank you !

Collapse
 
nhanne249 profile image
Nguyễn Ngô Vũ Nhân • Edited

Another question
If I want to config Route by Role, I should devide Route by two routes User and Admin or I just put all into a file and add one variety role like below



const routes = [
  {
    path: '/admin',
    role: 'admin'
    element: BlogLayout,
    children: [
      { path: '/', element: BlogList },
      { path: '/:postId', element: BlogPost },
    ],
  },
{
    path: '/user',
    role: 'user'
    element: Profile,
    children: [
      { path: '/', element: Profile},
      { path: '/:postId', element: Profile},
    ],
  },
];


Enter fullscreen mode Exit fullscreen mode
Collapse
 
nhanne249 profile image
Nguyễn Ngô Vũ Nhân

In your code should I use this code



const routes = [
  {
    path: '/blog',
    element: BlogLayout,
    children: [
      { path: '/', element: BlogList },
      { path: '/:postId', element: BlogPost },
    ],
  },
];



Enter fullscreen mode Exit fullscreen mode

or this



const routes = [
  {
    path: 'blog',
    element: BlogLayout,
    children: [
      { path: '*', element: BlogList },
      { path: ':postId', element: BlogPost },
    ],
  },
];



Enter fullscreen mode Exit fullscreen mode
Collapse
 
nhanne249 profile image
Nguyễn Ngô Vũ Nhân

Thank you!