When deploying a React application to S3 using React Router, child routes are not rendered correctly. I have solved 403 and 404 errors
<p>First I would like to point out that I have taken the troubleshooting steps to resolve errors 403 and 404 that are commonly associated with this issue in other threads on Stack Overflow. This includes setting the CloudFront error page to redirect to /index.html on errors 403 and 404. I also tried using the Lambda@Edge function to rewrite the URL. </p>
<p>The problem I'm having is that when I navigate to the root directory, my react page (using react router) is being served correctly from aws. But when I try to navigate directly to the subroute, nothing seems to render. However, when I serve the same production version on my local machine, there is no problem. </p>
<p>This is a public link for reference</p>
<p>Please note that if you navigate directly to the link, there will be no problem. However, if you navigate to https://d1e06h60n3f04n.cloudfront.net/preview/assetId, nothing will be rendered. The preview page code is as follows: </p>
<pre class="brush:php;toolbar:false;">import React, { useEffect, useState } from 'react';
import { useParams } from 'react-router';
import { BlogPreview } from './BlogPreview';
export interface IBlogPostData {
title: string;
content: string;
}
export function BlogPreviewForm() {
console.log("Loading blog preview form");
var { postId } = useParams();
const [blogPostData, setBlogPostData] = useState<IBlogPostData>({ title: "", content: "" });
useEffect(() => {
async function loadPost() {
var fileContent = await fetch(`previews/${postId}`);
setBlogPostData(await fileContent.json());
}
loadPost();
}, []);
return (
<div>
<div>Blog Preview</div>
<BlogPreview title={blogPostData?.title} content={blogPostData?.content} />
<label>Api Key</label>
<input type="text"></input>
<button>SUBMIT</button>
</div>
);
}</pre>
<p>The page should get the asset from assetId and load it. </p>
<p>My index html: </p>
<pre class="brush:php;toolbar:false;">import ReactDOM from 'react-dom/client';
import './index.css';
import { AppRoutes } from './Routes';
import reportWebVitals from './reportWebVitals';
import { createBrowserRouter, RouterProvider } from 'react-router-dom';
const routes = createBrowserRouter(AppRoutes);
const root = ReactDOM.createRoot(
document.getElementById('root') as HTMLElement
);
root.render(
<React.StrictMode>
<RouterProvider router={routes} />
</React.StrictMode>
);
reportWebVitals();</pre>
<p>and my route definition: </p>
<pre class="brush:php;toolbar:false;">export const AppRoutes: RouteObject[] = [
{
element: <App />,
path: '/',
children: [{
path: 'preview',
children: [{
path: '/preview/:postId',
element: < BlogPreviewForm />
}]
}]
}
]</pre>
<p>I'm pretty sure this has something to do with CloudFront and S3 since it renders fine locally, so I'm not sure posting the relevant code would help much, which is why I'm linking to the URL. </p>
<p>S3 configuration for reference:</p>