k1LoW / serverless-s3-sync

A plugin to sync local directories and S3 prefixes for Serverless Framework :zap:
182 stars 68 forks source link

SPA with react + react-router #77

Open theskillwithin opened 3 years ago

theskillwithin commented 3 years ago

Is there a way to configure this for use with a Single Page Application. Currently using react-router and if you refresh a route or link to a route other than root it sends the page as a 404. It appears to work for the user because ErrorDocument also points to index.html, however if you open up the console you can see it is serving it as a 404 page

ipatka commented 3 years ago

Yes, I've managed to get this working but it takes a few steps.

First, remove the .html suffix from all files except index.html

find . \( -iname "*.html" ! -iname "index.html" \) -exec sh -c 'mv "$0" "${0%.html}"' {} \;

However this will cause the content-type to be wrong in S3 so you have to specify defaultContentType

serverless.yml

  s3Sync:
    - bucketName: ${opt:domain}
      localDir: ${opt:htmlSrc}
      defaultContentType: text/html

Now you'll have an issue where your js and css files are type html, so you have to separate those out first. In my case I'm exporting a next.js static site so this is in the _next folder

mv _next ../

Then sync that one separately without the defaultContentType. Your Serverless.yml may look like this

  # S3 sync plugin configuration
  s3Sync:
    - bucketName: ${opt:domain}
      localDir: ${opt:htmlSrc}
      defaultContentType: text/html
    - bucketName: ${opt:domain}
      bucketPrefix: _next
      localDir: ${opt:stylingSrc}

Here's all the steps together in a gitlabCI file

deploy-static-site:
  stage: deploy-site
  before_script:
    - npm config set prefix /usr/local
  script:
  # Clients
    - cd clients/[client_name]
    - npm ci
    - npm run build && npm run export
    - cd out
    - mv _next ../
    - find . \( -iname "*.html" ! -iname "index.html" \) -exec sh -c 'mv "$0" "${0%.html}"' {} \;
  # Client Infra
    - cd ../../infra
    - npm ci
    - npx serverless deploy --domain [your_domain] --htmlSrc "../[client_name]/out" --stylingSrc "../[client_name]/_next" 
theskillwithin commented 3 years ago

@ipatka thanks but I believe the nextjs static generation is similar to gatsby where its generating static html files. I am doing a very straight forward old school react SPA where there is only 1 html file. no html files are generated. so I am afraid your method won't work for me. Thank you tho!