React app in S3 returns 404 error with document type when refresh page

Viewed 117

My React app running inside S3. I have set S3 to host my app and make index document and error document to index.html. The app is running well on the S3 link, however, when I refresh the page, even the app is still running correct, the devtool shows document 404 error.

I use webpack for build the app. With webpack devServer, I don't have this issue. Here is my webpack file:

const { resolve } = require("path")
const webpack = require("webpack")
const HtmlWebPackPlugin = require("html-webpack-plugin")
const MiniCssExtractPlugin = require("mini-css-extract-plugin")
const { CleanWebpackPlugin } = require("clean-webpack-plugin")
const Dotenv = require("dotenv-webpack")

module.exports = {
    mode: process.env.NODE_ENV === "development" ? "development" : "production",
    devtool: "source-map",
    entry: ["react-hot-loader/patch", "./src"],
    output: {
        path: resolve(__dirname, "dist"),
        filename: "[name].[chunkhash:5].js",
        chunkFilename: "[name].[chunkhash:5].js",
        publicPath: "/",
    },
    devServer: {
        contentBase: resolve(__dirname, "static"),
        compress: true,
        port: 3000,
        open: true,
        hot: true,
        historyApiFallback: true,
        proxy: {
            "/api": "http://localhost:5000",
        },
    },
    resolve: {
        alias: {
            "@": resolve(__dirname, "src"),
        },
        extensions: [".js", ".jsx"],
    },
    module: {
        rules: [
            {
                test: /\.(js|jsx)$/,
                exclude: /node_modules/,
                use: [
                    {
                        loader: "babel-loader",
                        options: {
                            presets: [
                                [
                                    "@babel/preset-env",
                                    {
                                        targets: "> 0.25%, not dead",
                                    },
                                ],
                                ["@babel/preset-react"],
                            ],
                            plugins: [
                                ["react-hot-loader/babel"],
                                ["@babel/plugin-proposal-class-properties", { loose: false }],
                                [
                                    "@babel/plugin-transform-runtime",
                                    {
                                        corejs: 3,
                                        helpers: true,
                                        regenerator: true,
                                    },
                                ],
                            ],
                        },
                    },
                ],
            },
            {
                test: /\.css$/,
                use: [
                    process.env.NODE_ENV === "development" ? { loader: "style-loader" } : MiniCssExtractPlugin.loader,
                    {
                        loader: "css-loader",
                        options: {
                            importLoaders: 1,
                        },
                    },
                    {
                        loader: "postcss-loader",
                        options: {
                            postcssOptions: {
                                plugins: [
                                    [
                                        "postcss-preset-env",
                                        {
                                            browsers: "last 10 version",
                                        },
                                    ],
                                ],
                            },
                        },
                    },
                ],
            },
            {
                test: /\.less$/,
                use: [
                    MiniCssExtractPlugin.loader,
                    "css-loader",
                    {
                        loader: "postcss-loader",
                        options: {
                            postcssOptions: {
                                plugins: [
                                    [
                                        "postcss-preset-env",
                                        {
                                            browsers: "last 10 version",
                                        },
                                    ],
                                ],
                            },
                        },
                    },
                    "less-loader",
                ],
            },
            {
                test: /\.(txt|csv|xlsx|mmdb)$/,
                use: [
                    {
                        loader: "file-loader",
                    },
                ],
            },
            {
                test: /\.(jpg|png|gif|bmp)$/,
                use: [
                    {
                        loader: "url-loader",
                        options: {
                            name: "[hash:10].[ext]",
                            esModule: false,
                            limit: 10 * 1024,
                            outputPath: "images",
                            publicPath: "/images",
                        },
                    },
                ],
            },
            {
                test: /\.html$/i,
                loader: "html-loader",
            },
        ],
    },
    plugins: [
        new Dotenv({
            path: resolve(__dirname, "./.env"),
            systemvars: true,
        }),
        new HtmlWebPackPlugin({
            template: "./src/index.html",
            filename: "./index.html",
        }),
        new MiniCssExtractPlugin({
            filename: "[name].[contenthash:5].css",
        }),
        new CleanWebpackPlugin(),
        new webpack.HotModuleReplacementPlugin(),
    ],
}

My route file is like

<BrowserRouter>
    <Switch>
        <Route path="/a" component={A} />
        <Route path="/b" component={B} />
        <Route path="/c" component={C} />
        <Route path="/d" component={D} />
        <Route component={Admin} />
    </Switch>
</BrowserRouter>

I don't know if S3 or webpack made this issue.

enter image description here

0 Answers
Related