0

I am new to React. I created a nested route which works perfectly on local across different devices. However, when I deploy it on GCP nginx server, the nested routing seems to have been ignored if I directly visit the path. Contrastly, it seems to work well when the path was pushed by a button, which I do not understand.

I have a routes.js

<Router history={history}>
  <Switch>
    <Route exact path="/" component={Home} />
    <Route path="/about" component={About} />
    <Route path="/admin" component={Admin} />
    <ProtectedRoute path="/message" component={Message} />
    <Route path="/profile" component={Profile} />
    <Route path="*" component={() => <h1 style={{ textAlign: "center" }}>404 NOT FOUND</h1>} />
  </Switch>
</Router>

Taking in /profile, I have nested routes

const { path, url } = this.props.match;

...codes between...

<Switch>
  <Route path={`${url}/seller`} component={SellerProfile} />
  <ProtectedRoute path={`${url}/user`} component={UserProfile} />
  <Route path={`${url}/motto`} component={mottoProfile} />
  <Route path={`${url}*`} component={() => <h1 style={{ textAlign: "center" }}>404 NOT FOUND</h1>} />
</Switch>

Again, locally, all the components were rendered correctly. However, when deployed on server, visting the nested routes (ie /profile/motto) directly would return a blank page.

Despite that, when I use history.push, I am able to visit those nested routes. For instance, I have a function in another component that can successfully visit the nested routes.

const onProfile = (e) => {
  const cookies = new Cookies();
  props.history.push({
    pathname: "/profile/user",
    state: { userid: this.state.userid },
  });
}

Note that profile/motto does not require a state and its not the only nested routes that behave the same.

yjt11
  • 1
  • 1

1 Answers1

0

During my search I was taken here - it's not a direct answer about nginx, but for GCP load balancer in front of a bucket. Posting since others might be looking for the same.

Here is good background information: react router doesn't work in aws s3 bucket

What worked for me is to rewrite url with /index.html similar to forwarding the 404 errors solution above. This works clean and returns 200 code, but only works for 1 level, so paths "/", "/users" work, but path = "/user/*" and trying "/user/someuser" does not work. Here is the url map:

yourmapname.yaml:

defaultService: https://www.googleapis.com/compute/v1/projects/yourprojectname/global/backendBuckets/yourbucketname                                                                                                          
hostRules:                                                                                                                                                                                                                            
- hosts:                                                                                                                                                                                                                              
  - yourhostname                                                                                                                                                                                                         
  pathMatcher: path-matcher-2                                                                                                                                                                                                         
kind: compute#urlMap                                                                                                                                                                                                                  
name: yourmapname                                                                                                                                                                                                               
pathMatchers:                                                                                                                                                                                                                         
- defaultService: https://www.googleapis.com/compute/v1/projects/yourprojectname/global/backendBuckets/yourbucketname                                                                                             
  name: path-matcher-2                                                                                                                                                                                                                
  pathRules:                                                                                                                                                                                                                          
  - paths:                                                                                                                                                                                                                            
    - /                                                                                                                                                                                                                               
    - /user                                                                                                                                                                                                                           
    - /users                                                                                                                                                                                                                          
    service: https://www.googleapis.com/compute/v1/projects/yourprojectname/global/backendBuckets/yourbucketname                                                                                                  
    routeAction:                                                                                                                                                                                                                      
      urlRewrite:                                                                                                                                                                                                                     
        pathPrefixRewrite: /index.html                         
cloud compute url-maps import yourmapname \                                                                                                                                                                            
                --source ./gcp/yourmapname.yaml \                                                                                                                                                                               
                --global                                                                                                                                                                                                            

Same principle of rewriting to index.html works in nginx.