search

Home  >  Q&A  >  body text

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>
P粉501007768P粉501007768439 days ago595

reply all(1)I'll reply

  • P粉585541766

    P粉5855417662023-09-03 09:34:32

    At some point during the troubleshooting process, I set the homepage variable in package.json to "."

    I looked in the developer window of my browser and saw that all the files in the static directory located at the root of the s3 bucket were receiving a 404 error. This happens because it tries to create a path relative to the URL I'm loading: e.g. https://d29uq6a9kfzg1q.cloudfront.net/preview/static/js/ main.3351ea6b.js

    By removing the homepage "." from my package.json, it switched the path referencing the static directory to an absolute path in my index.html file: for example this solved the problem.

    reply
    0
  • Cancelreply