Search code examples
javascriptreactjsexpresscreate-react-appreact-router-dom

Express static files URL changes based on route


I have create-react-app thats using react-router-dom. I'm also using express server-side-rendering for SEO. Below is my simple express config. When I got to the '/' route or any of the first-level routes ("/contact", "/blog", etc), it works as intended. The static files come in as:

"http://localhost:8080/static/css/main.ec91a01d.css".

But when I navigate to any multi-level routes ("/blog/blog-post-1"), it adds the first route to the static files URl ex:

http://localhost:8080/blog/static/js/main.d9a1d852.js

What am I doing wrong? Also, the folder structure is that of a regular Create-react-app. Im serving my index.html from the build folder and my styles/js from build/static.

Project
----build
----public
...etc

And my server.js

const express = require('express');
const path = require('path');
const ssr = require('./ssr.mjs');

const app = express();

const crawler = async (req, res) => {
  const isBot = req.get('User-Agent').indexOf('Googlebot') > -1 || 
  req.get('User-Agent').indexOf('googlebot') > -1;
  if (isBot) {
    const { html } = await ssr(`http://www.example.com${req.path}`);
    return res.status(200).send(html);
  }
  res.sendFile(path.join(__dirname + '/build/index.html'));
};
app.use(express.static('build'));
app.get('/', crawler);

app.get('/process', crawler);
app.get('/work', crawler);
app.get('/contact', crawler);
app.get('/blog', crawler);
app.get('/blog/create-post', crawler);
app.get('/blog/:id', crawler);
app.get('/services', crawler);
app.get('/services/:id', crawler);
app.get('/payments', crawler);



const PORT = process.env.PORT || 8080;

app.listen(PORT, () => console.log('Server started. Press Ctrl+C to quit'));

Solution

  • You seem to be fetching your ressources with relative paths in your index.html, e.g.

    <script src="./static/js/main.d9a1d852.js"></script>
    

    What you want are absolute paths:

    <script src="/static/js/main.d9a1d852.js"></script>
    

    Notice the missing . at the beginning of the path.