'SSR React APP with Static router on express

I am trying to SSR a react application made from scratch on an express server. I am using Static Router. The html loads into browser and routing works but css and js bundle do not load. In network I get a 200 for js and css but the type of file is html. This is my first time rendering a React App with a router, server side. The app works perfectly when rendered client side. I only have one WebPack Config File

The error I am getting in terminal when running the ssr app is

No routes matched location "/static/client.js" 
No routes matched location "/static/client.7d7fcbbf9b1c53c6d706.css" 
No routes matched location "/static/client.7d7fcbbf9b1c53c6d706.css" 

If anyone has any idea on how I would be able to fix this issue it would be greatly appreciated! Thank you for your time. enter image description here

Express Config

const path=require('path');

const fs=require('fs');

const express=require('express');

const React = require('react');

const ReactDOMServer = require('react-dom/server');

const router = express.Router()

import {StaticRouter} from 'react-router-dom/server'

import Rout from '../src/Menu/router';

const app = express()

const PORT = 9001


const serverrender = (req, res, next)=>{
    const aa = ReactDOMServer.renderToString(<StaticRouter location={req.url}><Rout/></StaticRouter>)
    fs.readFile(path.resolve('./assets/index.html'), 'utf-8',(err, data)  => {
        if(err){
            console.log(err)
        }
        return res.send(data.replace('<div id="root"></div>',
         `<div id="root">${aa}</div>`))
    })
}
router.use(express.static(path.resolve(__dirname, '..', '/assets/static')))
router.use('/', serverrender)

app.use(router)
app.listen(PORT, ()=>{
    console.log(`${PORT}`)
})
WebPack Config
const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');

module.exports={
  mode: 'production',
  entry:{
    client: './src/index.js'
  },
  output:{
    path: path.resolve(__dirname, 'assets'),
    filename:"static/[name].js"
  },
  module:{
    rules:[
      {
         test: /\.js$/, exclude: /node_modules/, loader: "babel-loader",
         options: {
          // attach the presets to the loader (most projects use .babelrc file instead)
          presets: ["@babel/preset-env", "@babel/preset-react"]
        }
      },
      {test: /\.css$/i, use: [MiniCssExtractPlugin.loader,'css-loader']},
      {test: /\.(png|jpe?g|gif)$/i, use: ['file-loader']},
    ]
  },
  plugins: [new HtmlWebpackPlugin({ template: path.resolve(__dirname, 'src', 'index.html') }),
  new MiniCssExtractPlugin({ // [2]
    filename: 'static/[name].[hash].css'
 })],
  devServer: {
    //hot: true,
    //historyApiFallback: true,
  },
}
Package.json

{
  "dependencies": {
    "@babel/register": "^7.17.0",
    "axios": "^0.24.0",
    "express": "^4.17.2",
    "ignore-styles": "^5.0.1",
    "react": "^17.0.2",
    "react-dom": "^17.0.2",
    "react-responsive": "^9.0.0-beta.6",
    "react-router-dom": "^6.2.1"
  },
  "devDependencies": {
    "@babel/core": "^7.16.0",
    "@babel/plugin-transform-runtime": "^7.16.5",
    "@babel/preset-env": "^7.16.11",
    "@babel/preset-react": "^7.16.7",
    "babel-loader": "^8.2.3",
    "css-loader": "^6.5.1",
    "file-loader": "^6.2.0",
    "html-webpack-plugin": "^5.5.0",
    "isomorphic-style-loader": "^5.3.2",
    "mini-css-extract-plugin": "^2.5.3",
    "style-loader": "^3.3.1",
    "webpack": "^5.65.0",
    "webpack-cli": "^4.9.1",
    "webpack-dev-server": "^4.6.0"
  },
  "scripts": {
    "start": "webpack-dev-server --open",
    "build": "webpack",
    "ssr": "node server/index.js"
  }
}


Solution 1:[1]

Try this, I updated your express config code

const path = require("path");

const fs = require("fs");

const express = require("express");

const React = require("react");

const ReactDOMServer = require("react-dom/server");

const router = express.Router();

import { StaticRouter } from "react-router-dom/server";

import Rout from "../src/Menu/router";

const app = express();

const PORT = 9001;

const serverrender = (req, res, next) => {
  const aa = ReactDOMServer.renderToString(
    <StaticRouter location={req.url}>
      <Rout />
    </StaticRouter>
  );
  fs.readFile(path.resolve("./assets/index.html"), "utf-8", (err, data) => {
    if (err) {
      console.log(err);
    }
    return res.send(data.replace('<div id="root"></div>', `<div id="root">${aa}</div>`));
  });
};

// router.use(express.static(path.resolve(__dirname, '..', '/assets/static')))
// router.use('/', serverrender)

// root (/) should always serve our server rendered page
router.use("^/$", serverrender);

// other static resources should just be served as they are
router.use(
  express.static(path.resolve(__dirname, "..", "/assets/static"), {
    maxAge: "30d",
  })
);

// any other route should be handled by react-router, so serve the index page
router.use("*", serverrender);

app.use(router);
app.listen(PORT, () => {
  console.log(`${PORT}`);
});

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Anil Kumar