Serverless SSR for create-react-app
Full-featured AWS architecture to use Server-Side Rendering for any create-react-app project using Lambda, API Gateway, CloudFront. All infrastructure is configured using the AWS Cloud Development Kit and can be deployed using AWS CodePipeline and AWS CodeBuild.
Have fun, and be a nice anti-fascist human being!
https://d31tuk9nqnnpkk.cloudfront.net/
Guide (EN): React with server-side rendering on AWS Lambda on sbstjn.com
Guide (DE): React und server-side rendering mit AWS Lambda und CloudFront on superluminar.io
Whenever you search for server-side rendering of React applications, you will read it's hard to accomplish. But why? Most probably, you'll end up with frameworks like razzle or Next.js only because you wanted a little bit of pre-rendered HTML for your React application.
The idea of cra-serverless is pretty simple: Use your existing, un-ejected, and unpatched create-react-app and replace BrowserRouter
with StaticRouter
, deploy it to AWS Lambda, and finally put a CDN in front of it. You'll have your same React SPA, but now you can have pre-rendered HTML content for all routes in your application. This even works fine with frameworks like styled-components or apollo client for using GraphQL on AppSync.
Yes, this is serverless server-side rendering, so let's call it serverless pre-rendering for React. 🤯
- React with server-side rendering on AWS Lambda (English)
- React und server-side rendering mit AWS Lambda und CloudFront (German)
- TypeScript, for God's sake
- Basic un-ejected create-react-app stored
./src
- SSR using
react-dom/server
and koa in./server
- Infrastructure as Code using AWS Cloud Development Kit in
./aws
- AWS Lambda for server-side (pre-)rendering of React SPA
- Amazon CloudFront to cache pre-rendered HTML and serve assets from S3
- AWS CodePipeline and AWS CodeBuild for Continious Deployments
The primary goal for cra-serverless is to use a default create-react-app setup without any changes and avoid to eject it from react-scripts.
# Start your local environment as always
$ > yarn start
# Build your static SPA as always
$ > yarn build
You can develop and build SPA with the usual flow. Afterwards, you can run a local HTTP server with koa to test-drive your server-side rendering. The built project is intended to be uploaded to AWS Lambda, but you can deploy the Node.js application to other services as well.
# Start local server-side rendering service
$ > yarn run:local
# Build Node.js service for server-side rendering
$ > yarn build:server
All full-featured pipeline using AWS CodePipeline and AWS CodeBuild using the AWS Cloud Development Kit is included to support continious deployments. (Jump to Deployments and Configuration)
Most React applications use the react-router-dom
with BrowserRouter
:
import React from 'react'
import { BrowserRouter } from 'react-router-dom'
React.render(
<BrowserRouter>
<App />
</BrowserRouter>,
document.getElementById('root'),
)
Lucky us, a StaticRouter
exists as well and react-dom
has a function called renderToString
:
import { renderToString } from 'react-dom/server'
import { StaticRouter } from 'react-router-dom'
const markup = renderToString(
<StaticRouter location={path}>
<App />
</StaticRouter>,
)
Next, the value of markup
will be injected into your index.html
file and that's it. In a Nutshell, cra-serverless uses existing features of the frameworks you already use and wraps them in a serverless architecture with AWS Lambda.
Based on cra-pipeline, all you need is a personal GitHub Access Token and your own fork of this repository. If you have both things in place, store the token in AWS Systems Manager:
$ > aws secretsmanager create-secret \
--name GitHubToken \
--secret-string abcdefg1234abcdefg56789abcdefg \
--region us-east-1
{
"ARN": "arn:aws:secretsmanager:us-east-1:123456789001:secret:GitHubToken-uNBxTr",
"Name": "GitHubToken",
"VersionId": "4acda3d1-877f-4032-b38e-17bc50239883"
}
As everything is configured using AWS Cloud Development Kit, you need to prepare (aka bootstrap) your AWS account once for the usage of the CDK in your desired AWS region:
$ > yarn cdk bootstrap --region us-east-1
⏳ Bootstrapping environment aws://123456789001/us-east-1...
0/2 | 5:06:49 PM | CREATE_IN_PROGRESS | AWS::S3::Bucket | StagingBucket
0/2 | 5:06:50 PM | CREATE_IN_PROGRESS | AWS::S3::Bucket | StagingBucket Resource creation Initiated
1/2 | 5:07:11 PM | CREATE_COMPLETE | AWS::S3::Bucket | StagingBucket
✅ Environment aws://123456789001/us-east-1 bootstrapped.
Next, have a look at the ./config.ts
file in the root folder and configure at least the github
section of the file.
export const config = {
name: 'cra-serverless',
github: {
owner: 'sbstjn',
repository: 'cra-serverless',
},
env: { region: 'us-east-1' },
}
After changing the GitHub repository information, just deploy the CloudFormation stack for the included AWS CodePipeline and all resources will be created for you.
$ > yarn cdk deploy cra-serverless-pipeline
Pipeline: deploying...
Pipeline: creating CloudFormation changeset...
✅ Pipeline
Head over to the AWS Management Console and watch the beauty of a deploy pipeline and CloudFormation stacks. All resources will be created for you, and after a while a CloudFront Distribution is available for the included example application.
- sbstjn.com for a detailed guide in English
- superluminar.io for a detailed guide in German
Feel free to use the code, it's released using the MIT license.
You are welcome to contribute to this project! 😘
To make sure you have a pleasant experience, please read the code of conduct. It outlines core values and beliefs and will make working together a happier experience.