Dsabadash
Dsabadash

Reputation: 503

How to use react-router BrowserRouter in a static index.html file

I'm attempting to use the static index.html file generated by npm run build, along with react-router. the tl;dr is; i do not want a client server, I want the app to be loaded by opening the index.html file located in the build folder and still have BrowserRouter be able to route between components. At the moment, the page will load the 'home' component if I exclude the 'exact' prop in the route path, meaning it knows that it's out there somewhere, I just don't know how to configure the router to know that 'C:/Users/Myself/Project/app/build/index.html' is equal to the path of '/' and route to each component thereafter. if the exact prop is included, it just loads the standard 404 component. How should i configure the BrouserRouter basename, and/or the package.json "homepage" in order to route to the index.html-> load 'home' component when the page is initially opened?

things I do not want to do: - serve the build folder. - configure webpack - have the app accessible from 'http://localhost:XXXX' - change to use HashRouter (I want access to props.history.push)

In my mind, if the app can show the 'home'component without specifying exact, it means that it can reach it under certain circumstances, and i'm just not specifying what the index path is properly, i.e it is somewhere out there at like ../project/build/index.html/somewhere

I have already configured the package.json to have "homepage": ".", and have specified the BrowserRouter basename={'/build'}

My BrowserRouter:

<BrowserRouter basename={'/build'}>
   <Routes />
</BrowserRouter>

My routes.js file:

const Routes = (props) => {
  return (
    <div>
      <Switch>
        <Route path={routes.HOME} component={Home} />
        <Route render={(props) => <div>404 - Not Found</div>} />
      </Switch>

    </div>
  )
}

my package.json:

{
  "name": "cra",
  "version": "0.1.0",
  "private": true,
  "homepage": ".",
  "dependencies": {
    "react": "^16.8.6",
    "react-dom": "^16.8.6",
    "react-redux": "^7.0.2",
    "react-router-dom": "^5.0.0",
    "react-scripts": "2.1.8",
    "redux": "^4.0.1",
    "redux-logger": "^3.0.6",
    "redux-thunk": "^2.3.0"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  },
  "eslintConfig": {
    "extends": "react-app"
  },
  "browserslist": [
    ">0.2%",
    "not dead",
    "not ie <= 11",
    "not op_mini all"
  ],
  "devDependencies": {
    "node-sass": "^4.11.0"
  }
}

I want the end result to set c:/users/myself/project/app/build/index.html to equal route 'home' ('/').

I'm willing to accept that this is not possible, but as stated above, being able to access it from an inexact path leads me to believe i can make it exact and am just messing up the route config

Upvotes: 21

Views: 21995

Answers (4)

leaf
leaf

Reputation: 1764

If your application is hosted on a static file server, you need to use a <HashRouter> instead of a <BrowserRouter>.

v5 FAQ.md#why-doesnt-my-application-render-after-refreshing

For a website like www.example.com/path/to/index.html, you need to try a <HashRouter>.

For a website like www.example.com, <BrowserRouter> might work. The server like Nginx needs an extra config for proper renders after refreshing non-root pages.

location / {
   try_files $uri /index.html;
}

Upvotes: 16

Vinnie Vincente
Vinnie Vincente

Reputation: 1

I had the same problem and I solved it using this link here https://hostrain.in/help/deploy-host-react-app-in-cpanel/ step 5 or in your public_html folder, add a .htaccess file and add the following code and save

<IfModule mod_rewrite.c>

  RewriteEngine On
  RewriteBase /
  RewriteRule ^index\.html$ - [L]
  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteCond %{REQUEST_FILENAME} !-d
  RewriteCond %{REQUEST_FILENAME} !-l
  RewriteRule . /index.html [L]

</IfModule>

Please note that the .htaccess file is hidden and you should enable show hidden files in the settings of the file manager. Happy coding!

Upvotes: 0

eddex
eddex

Reputation: 2152

If you deploy your static site on DigitalOcean, you can specify all routes in the App Spec under Your App > Settings > App Spec.

Just add a path for each route to the file under static_sites > routes.

Each route will then be forwarded to your / route where it will be handled by react router.

More info: https://docs.digitalocean.com/products/app-platform/concepts/http-route/

Upvotes: 0

Mostafa Farz&#225;n
Mostafa Farz&#225;n

Reputation: 1003

You don't have to use HashRouter.

Just configure your static web server to serve index.html for all the routes that you've defined. If you're using Nginx for example, see this example config file. If you're using Apache or Express, see this.

Upvotes: 1

Related Questions