DEV Community

Cover image for Building a Modular React Layout for a Subdomain
TD!
TD!

Posted on

Building a Modular React Layout for a Subdomain

In modern web development, it's common to have different sections of an application that require distinct layouts, navigation, and styling. In my case, I needed to create a dedicated services page that had a completely different navbar and footer from the homepage. This article is the first in a five-part series where I walk you through how I built a modular React layout for a subdomain, starting with the fundamental structure and component breakdown.

Understanding the Need for a Separate Layout

In many web applications, especially those structured as Single Page Applications (SPAs), different sections may serve different user needs. The homepage often has a global navigation bar and footer that apply site-wide. However, in cases where a subdomain or a specific section of the site needs a distinct identity, using a separate layout becomes necessary.

Key Reasons for a Separate Layout:

  1. Branding & Design Consistency – A service page might require a professional or corporate feel, different from the main site.
  2. Performance Optimization – Loading only necessary assets for the section improves efficiency.
  3. Scoped Styles – Preventing CSS conflicts between the main site and the subdomain layout.
  4. Better Component Reusability – Breaking down UI into modular components enhances maintainability.

Setting Up the Project Structure

To keep things modular and manageable, I structured my React project like this:

/src
 ├── components
 │   ├── ServicesHeader.js
 │   ├── ServicesHero.js
 │   ├── machines/
 │   │   └── MachinesList.js
 │   ├── building/
 │   │   └── BuildingSection.js
 │   ├── production/
 │   │   └── ProductionSection.js
 │   ├── investment/
 │   │   └── InvestmentSection.js
 │   ├── certificates/
 │   │   └── CertificatesSection.js
 │   ├── ServicesContact.js
 │   ├── ServicesFooter.js
 ├── layouts
 │   ├── ServicesLayout.js
 ├── App.js
Enter fullscreen mode Exit fullscreen mode

This approach ensures that the services page has its own encapsulated components while still leveraging React’s modular architecture.

Breaking Down the Layout (ServicesLayout Component)

The ServicesLayout component serves as the primary layout for the services section. It contains a unique header and footer while encapsulating all the content sections within a <main> tag.

Implementing ServicesLayout.js

import React from 'react';
import { ServicesHeader } from './ServicesHeader';
import { ServicesHero } from './ServicesHero';
import { MachinesList } from './machines/MachinesList';
import { BuildingSection } from './building/BuildingSection';
import { ProductionSection } from './production/ProductionSection';
import { InvestmentSection } from './investment/InvestmentSection';
import { CertificatesSection } from './certificates/CertificatesSection';
import { ServicesContact } from './ServicesContact';
import { ServicesFooter } from './ServicesFooter';

export function ServicesLayout() {
  return (
    <div className="min-h-screen bg-gray-50">
      <ServicesHeader />
      <main>
        <ServicesHero />
        <MachinesList />
        <BuildingSection />
        <ProductionSection />
        <InvestmentSection />
        <CertificatesSection />
        <ServicesContact />
      </main>
      <ServicesFooter />
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode

Key Features of this Layout:

  1. Encapsulation – The layout is self-contained, allowing easy integration with routing.
  2. Component-Based Architecture – Each section is modular, making updates simpler.
  3. Separation of Concerns – The services page does not interfere with the main app’s layout.

Handling Global Styles vs. Scoped Styles

One challenge in having different layouts is ensuring that styles do not clash. Here’s how I managed styles effectively:

Using Tailwind CSS for Scoped Styles

Since I’m using Tailwind CSS, I applied scoped classes at the layout level.

/* Tailwind-based scoped styles */
.min-h-screen {
  min-height: 100vh;
}
.bg-gray-50 {
  background-color: #f9fafb;
}
Enter fullscreen mode Exit fullscreen mode

This approach ensures that the services page maintains a distinct look without affecting global styles.

Alternative: Using CSS Modules

For more explicit styling, you could use CSS Modules:

/* ServicesLayout.module.css */
.layoutContainer {
  min-height: 100vh;
  background-color: #f9fafb;
}
Enter fullscreen mode Exit fullscreen mode

Then, import it in ServicesLayout.js:

import styles from './ServicesLayout.module.css';

<div className={styles.layoutContainer}>
Enter fullscreen mode Exit fullscreen mode

Integrating the Layout with React Router

To ensure that this layout is used only when navigating to the services page, I configured React Router like this:

import { BrowserRouter as Router, Route, Routes } from 'react-router-dom';
import { ServicesLayout } from './layouts/ServicesLayout';
import { HomePage } from './HomePage';

function App() {
  return (
    <Router>
      <Routes>
        <Route path="/" element={<HomePage />} />
        <Route path="/services" element={<ServicesLayout />} />
      </Routes>
    </Router>
  );
}

export default App;
Enter fullscreen mode Exit fullscreen mode

What This Does:

  • Loads HomePage at /
  • Loads ServicesLayout at /services
  • Ensures a clean separation between different layouts

By structuring the application this way, I successfully built a modular React layout that serves as a subdomain with a distinct look and feel. This approach allows for flexibility, performance optimizations, and better maintenance of the codebase.

See the homepage navbar below:

Coconoto homepage

Day 3 of #60daysofcode

Top comments (0)