2

I have a ReactJS application which works very well on development environment. I am using webpack. When I run yarn build and I drop my files on my server, everything runs fine. but if I click refresh on the browser, I get a 404.

My server uses Apache. I have tried htaccess, I have done historyFallBackApi. None of them seem to solve my problem

Here is my .htaccess

RewriteBase /
RewriteCond %{REQUEST_URI} !^/(assets/?|$)
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.html [L]

Here is my webpack.config.js

const HtmlWebpackPlugin = require('html-webpack-plugin');

const modeConfig = env => require(`./config/webpack.${env}`)(env);
const webpackMerge = require('webpack-merge');
const path = require('path');


module.exports = (
    { mode } = { mode: 'development', presets: [] },
) =>
// console.log(`mode: ${mode}`);
    webpackMerge(
        {
            mode,
            entry: './src/index.js',
            resolve: {
                extensions: ['.js', '.jsx', '.css', 'scss'],
            },
            devServer: {
                historyApiFallback: { index: '/' },
                contentBase: './',
                open: true,
                port: 4100,
            },
            module: {
                rules: [
                    {
                        test: /\.(png|jpg|jpeg|gif|ico)$/,
                        exclude: /node_modules/,
                        loader: 'url-loader?limit=8192',
                    },
                    {
                        test: /\.(js|jsx|mjs)$/,
                        exclude: /node_modules/,
                        use: 'babel-loader',
                    },
                    {
                        test: /\.(woff|woff2|eot|ttf)$/,
                        loader: 'url-loader?limit=100000',
                    },
                    {
                        test: /\.svg$/,
                        loader: 'svg-inline-loader?classPrefix',
                    },
                ],
            },

            output: {
                publicPath: '/',
                path: path.resolve(__dirname, 'build'),
                filename: 'bundle.js',
            },
            plugins: [
                new HtmlWebpackPlugin({
                    template: './public/index.html',
                }),

                // new FaviconsWebpackPlugin({ logo: "./public/image.png" })
            ],
        },
        modeConfig(mode),
    );

Here is my route



function App() {
    return (
        <Router history={history}>
            <Switch>
                <Route exact path="/" component={LoginComponent} />
                <Route path="/reset-password" component={ResetPassword} />
                <Route path="/dashboard" component={Dashboard} />
                <Route path="/cards" component={CardsList} />
                <Route path="/view-card" component={ViewCard} />
                <Route path="/transactions" component={Transfer} />
                <Route path="/users" component={UsersList} />
                <Route path="/edit-user" component={EditUser} />
            </Switch>
        </Router>
    );
}

export default App;

Here is my custom history

import { createBrowserHistory } from 'history';

const history = createBrowserHistory();

export default history;

I keep getting 404 on Page refresh on the server.

  • 1
    I dont know about apache but the recurrent reason to get a 404 with frontend routing on a deployed app is that your server is not configured to serve a SPA (e.g. serving the html file and bundle.js on any route) – Gaël S Jun 18 '19 at 22:00
  • This code ```historyApiFallback: { index: '/' }``` is sending entry point bundle, if you can config the server as Gael mentioned as sending this bundle on every request this problem will resolve. It is the tricky part of CSR Routing. – tunaayberk Jun 19 '19 at 01:38
  • @GaëlS What if I switch to Nginx , it is still the same – Temi 'Topsy' Bello Jun 19 '19 at 09:51
  • I need someone to walk me through @tunaayberk – Temi 'Topsy' Bello Jun 19 '19 at 09:53
  • Hello @Temi'Topsy'Bello, you can check this post https://stackoverflow.com/a/16554242/11233593 . I never tried on apache, but this is what you need. I would try FallbackResource redirect rule. If that wont works for you, try ember.js like they suggested on that post. – tunaayberk Jun 19 '19 at 13:45

1 Answers1

3

I would update your .htaccess file to be like this. The problem is likely that what you are currently using as your .htaccess file does not redirect 404 errors to index.html:

RewriteEngine On  
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -f [OR]
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -d
RewriteRule ^ - [L]

RewriteRule ^ /index.html [L]

I would also add a custom 404 page. To do that, you need to create a new component and add another route to your switch. The route shouldn't have a path and should be the last route of the switch.

<Route component={NotFoundComponent} />

technogeek1995
  • 3,185
  • 2
  • 31
  • 52
  • 1
    I have not set this up through an `.htaccess` file before. I have had success with apache using [this tutorial](https://stackoverflow.com/a/48872476/1913185). – technogeek1995 Jul 09 '19 at 20:31
  • I just did this on my site. Worked great! no other steps were needed other than these lines in my .htaccess file (which I just created) – C Ruckman Apr 01 '23 at 00:15