Serverless-side rendering with Vue.js and Nuxt.js
This project demonstrates how to use Nuxt.js to create a server-side rendered Vue.js app on AWS Lambda and AWS API Gateway.
Use-cases
- Develop single-page apps without worrying about SEO optimization.
Benefits
- SEO boost server-side rendering provides
- Speed of a Single Page Application
- Cheap hosting in a serverless environment on AWS Lambda
- Easy deployment with the Serverless Framework
- Can easily integrate with your own API or 3rd party APIs such as headless CMS, e-commerce or serverless architecture.
How it works
Well, first thing's first. We want a super fast Single Page Application. But, this usually comes with a cost. Lousy SEO capabilities. That won't do, meaning we also want the app to have server-side rendering. Okay, sounds simple. We'll grab Nuxt.js, which is a framework for creating universal Vue.js applications, and configure it to server-side render our pages.
To accomplish this we need to spin up a simple Express server and configure the Nuxt renderer to serve files through Express. It is way simpler than it sounds.
Setup
- Install dependencies:
$ npm install
- Create public wildcard certificate for your domain (AWS ACM)
Deploy
-
Deploy service without custom domain:
$ npm run deployOutput:
> aws-node-vue-nuxt-ssr@1.0.0 deploy /home/raha/code/serverless/examples/aws-node-vue-nuxt-ssr> npm run build && sls deploy> aws-node-vue-nuxt-ssr@1.0.0 build /home/raha/code/serverless/examples/aws-node-vue-nuxt-ssr> nuxt buildHash: 969f557230f1916aaab2Version: webpack 4.31.0Time: 5531msBuilt at: 05/14/2019 12:22:28 AMAsset Size Chunks Chunk Names../server/client.manifest.json 6.81 KiB [emitted]1aeb026dc2ca77c8b429.js 952 bytes 3 [emitted] pages/dogs/index775caefedab77dd6e1a6.js 147 KiB 1 [emitted] commons.app92fcd17f0b85f40f90ad.js 1.15 KiB 2 [emitted] pages/dogs/_breed9f5aaac1c101c273e65f.js 845 bytes 4 [emitted] pages/indexLICENSES 464 bytes [emitted]cf8b2abbbaec4a0c7b76.js 2.27 KiB 5 [emitted] runtimefa6324eac05d1b7d36b0.js 42.3 KiB 0 [emitted] app+ 2 hidden assetsEntrypoint app = cf8b2abbbaec4a0c7b76.js 775caefedab77dd6e1a6.js fa6324eac05d1b7d36b0.jsHash: ac61088f50920f2fc1a4Version: webpack 4.31.0Time: 1266msBuilt at: 05/14/2019 12:22:30 AMAsset Size Chunks Chunk Names92cd2f7d0e5f9c484439.js 641 bytes 2 [emitted] pages/dogs/indexbbeb65244f57ade7cfbe.js 828 bytes 1 [emitted] pages/dogs/_breede3465bc88d2bf9e1b91d.js 536 bytes 3 [emitted] pages/indexserver.js 25.1 KiB 0 [emitted] appserver.manifest.json 483 bytes [emitted]+ 4 hidden assetsEntrypoint app = server.js server.js.mapDone in 9.03sServerless: Packaging service...Serverless: Excluding development dependencies...Serverless: Creating Stack...Serverless: Checking Stack create progress........Serverless: Stack create finished...Serverless: Uploading CloudFormation file to S3...Serverless: Uploading artifacts...Serverless: Uploading service .zip file to S3 (42.47 MB)...Serverless: Validating template...Serverless: Updating Stack...Serverless: Checking Stack update progress....................................Serverless: Stack update finished...Service Informationservice: serverless-side-rendering-vue-nuxtstage: devregion: us-east-1stack: serverless-side-rendering-vue-nuxt-devapi keys:Noneendpoints:ANY - https://<api_id>.execute-api.us-east-1.amazonaws.com/devANY - https://<api_id>.execute-api.us-east-1.amazonaws.com/dev/{proxy+}functions:nuxt: serverless-side-rendering-vue-nuxt-dev-nuxtOnce deployed you'll have your app running on a default API Gateway URI.
-
Create domain:
Uncomment domain settings in
serverless.yaml
.[...]plugins:- serverless-apigw-binary- serverless-domain-manager # uncomment the plugin- serverless-offline[...]custom:secrets: ${file(secrets.json)}apigwBinary:types:- '*/*'customDomain: # uncomment the whole customDomain sectiondomainName: ${self:custom.secrets.DOMAIN}basePath: ''stage: ${self:custom.secrets.NODE_ENV}createRoute53Record: trueRun the create domain command:
$ sls create_domainThis will take a few minutes, go grab a coffee in the meantime. :smile:
-
Re-deploy the service with the domain settings:
$ npm run deployOutput:
[...same as above but also with the domain info]Serverless Domain Manager SummaryDomain Namevuessr.yourdomain.comDistribution Domain Name<cdn_id>.cloudfront.net
Usage
Navigate to vuessr-yourdomain.com
or whichever domain you picked. You'll see the Vue.js SPA running.
I've written a detailed tutorial about the process. You can check it out here. (NOTE: Some parts are outdated and are for nuxt@1
. Please refer to this example for using with nuxt@2
)