CSS not working for nested routing in react js

4.1k views Asked by At

I am new to working with frontend and react js. I have installed a template in my application. index.html file contain all links and path for css

 index.html
 <html lang="en">
 <head>
<meta charset="utf-8" />
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
 
 { all the css links and scripts goes here}


</body>
</html>

This is my app.js file. Here I have mentioned my upper level routes

import logo from './logo.svg';
import './App.css';
import Layout from '../src/Components/Layout/Layout'
import LoginScreen from './Components/Login/LoginScreen'
import { BrowserRouter as Router, Route } from "react-router-dom";

function App() {
  return (
     <div className="App">

      <Router>
          <Route path="/pages" component={Layout}/>
          <Route path="/login" component={LoginScreen} exact />
      </Router>

    </div>
  );
 }

 export default App;

This is my Layout component which consist of all the screen components (lower level routes)

 import React from "react";
 import { BrowserRouter as Router, Route } from "react-router-dom";
 import css_class from "./Layout.module.css";
 import Navbar from '../Navbar/Navbar';
 import TopNavbar from '../TopNavbar/TopNavbar'
 import Home from '../Home/Home'
 import About from '../About/About'
 import OurProject from '../OurProject/OurProject'

 function Layout() {
    return (
      <body>


      <Router>

        
        <TopNavbar/>

        
        <div class="pcoded-main-container">
            <div class="pcoded-wrapper">
                <nav class="pcoded-navbar">
                    <div class="sidebar_toggle"><a href="#"><i class="icon-close icons"></i></a> 
         </div>
                    <div class="pcoded-inner-navbar main-menu">
                        <div class="">
                            <div class="main-menu-header">
                                <img class="img-80 img-radius" style={{height:'7.9em'}} 
                                src="/divylogo.png" alt="User-Profile-Image" />
                            </div>

                            <div class="main-menu-content">
                                <ul>
                                    <li class="more-details">
                                        <a href="user-profile.html"><i class="ti-user"></i>View 
                                         Profile</a>
                                        <a href="#!"><i class="ti-settings"></i>Settings</a>
                                
                                    </li>
                                </ul>
                            </div>
                        </div>

                        
                      <Navbar />
                    </div>
                </nav>
                   
                    <div class="pcoded-inner-content">
                  
                        <div class="main-body">
                            <div class="page-wrapper">

                            
                               
                                <div class="page-body">
                                    

                                    {/* ##################################### */}
                                    <Route path="/" component={Home} exact />
                                    <Route path="/crausal/:id/edit" component={HomeSec2Sub} />
                                    <Route path="/about" component={About} />
                                    <Route path="/ourproject" component={OurProject} />
                                    <Route path="/projects" component={Projects} />
                                    {/* ##################################### */}
                                </div>
                            
                            
                              
                            </div>
                        </div>
                   

                        <div id="styleSelector">

                        </div>
                    </div>
                </div>
            </div>
        </div>
        </div>
</div>


<script src="assets/js/jquery.mCustomScrollbar.concat.min.js "></script>


<script src="assets/js/pcoded.min.js"></script>
<script src="assets/js/vertical/vertical-layout.min.js "></script>

<script type="text/javascript" src="assets/js/script.js "></script>
</Router>
</body>

);
}

export default Layout;

But somehow my pages i.e layout components are not getting any css. In my app.js file if I change the route of Layout component from (pages/) to (/), then everything works. But if I use (pages/ as route) I am not getting any css for my sub routes mentioned in Layout component.

3

There are 3 answers

0
Drew Reese On BEST ANSWER

Issue

What I am saying is if I give path like this (<Route path="/" component={Layout}/>) It works. But If I use anything else with ("/") this like ("/pages", "/subfiles" etc) The css does not works for them.

As soon as the path is anything other than "/pages" then Layout component is no longer mounted (along with the css it imported). The reason it works with "/" is because "/" is a path prefix for all paths and will always match.

Yes I want it like this ("pages/about" etc).

Solution

If you want "/pages" as a path prefix to the nested paths then they need to actually be nested.

  1. Import Switch and useRouteMatch hook from react-router-dom. The useRouteMatch hook allows you to access the current path so you can build nested routes upon it, and the Switch is so you are matching and rendering only one sub-route.
  2. Remove the nested Router component, you need only one Router component to provide a routing context.
  3. Remove the body and script tags. You need only one body tag per HTML document and the script tags can be declared in your index.html file.

Code:

import { Route, Switch, useRouteMatch } from "react-router-dom";

function Layout() {
  const { path } = useRouteMatch();

  return (
    <>
      <TopNavbar />

      <div class="pcoded-main-container">
        <div class="pcoded-wrapper">
          ...

          <div class="pcoded-inner-content">
            <div class="main-body">
              <div class="page-wrapper">
                <div class="page-body">
                  <Switch>
                    <Route
                      path={`${path}/crausal/:id/edit`}
                      component={HomeSec2Sub}
                    />
                    <Route path={`${path}/about`} component={About} />
                    <Route path={`${path}/ourproject`} component={OurProject} />
                    <Route path={`${path}/projects`} component={Projects} />
                    <Route path={path} component={Home} />
                  </Switch>
                </div>
              </div>
            </div>

            <div id="styleSelector"></div>
          </div>
        </div>
      </div>
    </>
  );
}

For more see nesting example from react-router-dom.

1
Fernando On

If it is the same problem I had, solution is to use absolute paths (beginning with /) for all assets in your index.html file.

As index.html is a static file, when you load it on a route as /products/productId, the relative path points to /products/style.css, where file is not found.

So in index.html change this:

<link rel="stylesheet" href="./style.css" media="all" />

For this:

<link rel="stylesheet" href="/style.css" media="all" />
0
Yogesh Yadav On

I also have the same problem. My CSS file giving status code of 500 on nested routes in react-router-dom but working fine with root route.

error on reading css file

I fix this issue using following step:

  1. remove my CSS file from public/main.css
  2. add my css file at source root level -> src/main.css
  3. import my css file into index.js -> import './main.css';

P.S - I'm using create-react-app