grpcMe
grpcMe

Reputation: 1417

Can't navigate to react-router-dom URL's

There are a few topics on SO like this one which recommends changing Webpack and this one that recommends setting up a catch-all.

I am using react-router-dom for three routes; similar story to the rest of the questions on here, the / path works but neither /cars or /about does.

import React, {Component} from 'react';
import {render} from 'react-dom';
import {BrowserRouter, Route, Switch, Link} from 'react-router-dom';


const Home = () => (
  <h1>Home</h1>
)

const Car = () => (
  <h1>Cars</h1>
)

const About = () => (
  <h1>About</h1>
)

render(
  <BrowserRouter>
    <Switch>
      <Route exact path="/" component={Home}/>
      <Route exact path="/cars" component={Car}/>
      <Route path="/about" component={About}/>
    </Switch>
  </BrowserRouter>,
  document.getElementById('container')
);

I have tried adding a publicPath and historyApiFallback into my webpack config:

module.exports = {
  entry: ['./src/index.jsx'],
  output: {
    path: path.resolve('public'),
    filename: 'bundle.js',
    publicPath: '/'
  },
  module: {
    loaders: [
      {test: /\.js$/,loader: 'babel-loader',exclude: /node_modules/},
      {test: /\.jsx$/,loader: 'babel-loader',exclude: /node_modules/}
    ]
  },
  devServer: {
    historyApiFallback: true
  }
}

But as soon as I navigate to http://localhost:8080/cars I get a Cannot GET /cars message on the browser and a load of errors similar to this:

Refused to load the font 'data:font/woff;base64,d09GRgABAAAAAGz8ABEAAAAA09gAAQABAAAAAAAAAAAAAAAAAAAAAAAAAABHREVGAAABgAAAAC8AAAA0AsQC9UdQT1MAAAGwAAATuAAANLwBEyF1R1NVQgAAFWgAAAIWAAAEZqfk0PVPUy8yAAAXgAAAAFAAAABgaNCCw2NtYXAAABfQAAABkwAAAkQk8AV7Y3Z0IAAAGWQAAABiAAAAugGiQq9mcGdtAAAZyAAABZcAAAvNb3/BHGdhc3AAAB9gAAAACAAAAAgAAAAQZ2x5ZgAAH2gAAESvAAB8yu28l3FoZWFkAABkGAAAADYAAAA2BmibVWhoZWEAAGRQAAAAIAAAACQHMQRzaG10eAAAZHAAAAJDAAAEImBmMbxsb2NhAABmtAAAAhoAAAIaflxdR21heHAAAGjQAAAAIAAAACACjgzgbmFtZQAAaPAAAACdAAABKBQEL8lwb3N0AABpkAAAAsMAAAS9pi3QFXByZ...w76a3jVVUpJzXkBsRtNQoHWTV2mt2UusrulbnIrkvAXNBDFtTVIB8Uoau4pSruq4q7qq2dHpQADUAT0IJ5ra0yPUAfMACMFY6pOtegV/9D7UtTZx72tTeXI4JdcUXh7Pb67D7I/S05AwjAAiYsNie6WOwc4MiYCORSEx+ZExuCvQpiNSRmAdL8wDs2AslUOgp8HfnSYyfCYjrE7w8QDucyS0aXjH0zGk7FX991RgON6L7Qma6pQ+SzA0Qw1x9+HgNFtrBk+F9RsmDpTShvNJL4BDWtP8IAeAFj8N7BcCIoYiMjY1/kBsadHAwcDMkFGxnYnLZFMFgwMLAyaIE4DjzeHPYs+mzKLOIsrBxQoVA2VyZzFk0mWSawELfTPmEGAQYeBk4GNpBGTqCYgNM+BgcYhIgxM7hsVGHsCIzY4NARsZE5xWWjGoi3i6OBgZHFoSM5JAKkJBIIHHh8ORxZDNlUWSRZWHm0djD+b93A0ruRicFlA1vcRtYUFwBQJimV' because it violates the following Content Security Policy directive: "default-src 'self'". Note that 'font-src' was not explicitly set, so 'default-src' is used as a fallback.

Upvotes: 8

Views: 3521

Answers (2)

MichaelB
MichaelB

Reputation: 1362

I had the same problem and was able to solve it by changing my server implementation to use express with "catch all and send to index.html" as suggested by OmisNomis.

Adding here my server.js code for anyone who has no previous knowledge of express

const express = require("express")
const path = require("path")
const app = express()

app.use(express.static(__dirname))
app.get('*', (req, res) => res.sendFile(path.join(__dirname, '/index.html')))
app.listen(8080)

console.log("Running at Port 8080")

Upvotes: 0

grpcMe
grpcMe

Reputation: 1417

Typically after trying to figure this out on my own for 30 minutes, getting frustrated and posting on SO; I figured it out 2 minutes after...!

The configuration I added into my webpack file was pointless; seeing as I am serving my files using express

The catch-all method was what I needed, but I had done it wrong. You have two options. Do a proper "catch all" and send everything to the HTML file...

app.get('*', (req, res) => {
  res.sendFile(appRootPath + '/public/index.html');
});

or, if like me, you want to only send a specific endpoint, so you can still manage 'other things' you can...

app.get('/react*', (req, res) => {
  res.sendFile(appRootPath + '/public/index.html');
});

A specific mention, because this is what tripped me up, make sure you do /react*/ and not /react/*

I could then update my Routes to the following and browse to them directly...

render(
  <BrowserRouter>
    <Switch>
      <Route exact path="/react" component={Home}/>
      <Route exact path="/react/car" component={Car}/>
      <Route path="/react/about" component={About}/>
    </Switch>
  </BrowserRouter>,
  document.getElementById('container')
);

Heres an example where I typed in a random URL

Upvotes: 4

Related Questions