That’s a mouthful of a title right there. Don’t let it scare you away. What it boils down to is rather simple. We want the best of both worlds. The SEO boost server-side rendering provides, and the speed of a Single Page Application. All this while hosted basically for free in a serverless environment on AWS Lambda. TL;DR Here’s a quick overview of what we’ll be building for you to get up to speed. Feel free to jump to the step that interests you the most. Don’t mind me guilt tripping you into reading the whole thing… * * 😐 stares guilt trippingly What’re we building? Configure and install dependencies Build the app with the and Serverless Framework Nuxt.js Deploy the app to AWS Lambda Test the app with Dashbird Note : The code we will write is already on GitHub if you need further reference or miss any steps, feel free to check it out. What’re we building? 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 , which is a framework for creating universal applications, and configure it to server-side render our pages. Nuxt.js Vue.js 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. However, the key takeaway here is the word . Ew, we don’t like mentioning that word. So, what do we need to do? Well, deploy this whole application to ! It is a tiny Node.js instance after all. server AWS Lambda But this raises a concern. How to monitor and debug it if everything goes horribly wrong? I usually have opened in a separate tab to monitor all my serverless resources in real time. Dashbird Phew, with that out of the way, let’s get crackin’! Configure and install dependencies As always, we’re starting with the boring part, setting up the project and installing dependencies. 1. Install the Serverless Framework In order for serverless development to be absolute torture, go ahead and install the . not Serverless framework $ npm i -g serverless Note: If you’re using Linux or Mac, you may need to run the command as _sudo_ . Once installed globally on your machine, the commands will be available to you from wherever in the terminal. But for it to communicate with your AWS account you need to configure an IAM User. Jump over , then come back and run the command below, with the provided keys. here for the explanation $ serverless config credentials \ --provider aws \ --key xxxxxxxxxxxxxx \ --secret xxxxxxxxxxxxxx Now your Serverless installation knows what account to connect to when you run any terminal command. Let’s jump in and see it in action. 2. Create a service Create a new directory to house your Serverless application services. Fire up a terminal in there. Now you’re ready to create a new service. What’s a service you ask? View it like a project. But not really. It’s where you define AWS Lambda functions, the events that trigger them and any AWS infrastructure resources they require, all in a file called . serverless.yml Back in your terminal type: $ serverless create \ --template aws-nodejs \ --path serverless-side-rendering-vue-nuxt The create command will create a new . Shocker! But here’s the fun part. We need to pick a runtime for the function. This is called the . Passing in will set the runtime to Node.js. Just what we want. The will create a folder for the service. service template aws-nodejs path 3. Install npm modules Change into the folder in your terminal. There should be three files in there, but for now, let’s first initialize npm. serverless-side-rendering-vue-nuxt After the file is created, you can install a few dependencies. package.json $ npm i axios nuxt express serverless-http serverless-apigw-binary These are our production dependencies, and I’ll go into more detail explaining what they do a bit further down. Apart from them, we need one more as a development dependency. This one will let us tie a domain to our endpoints. Sweet! $ npm i --save-dev serverless-domain-manager Now, your should look something like this. package.json We also need to add two scripts, one for running on our local dev machine and one for building and deploying the app. You can see them in the section of the . nuxt scripts package.json 4. Configure the serverless.yml file Moving on, let’s finally open up the project in a code editor. Check out the file, it contains all the configuration settings for this service. Here you specify both general configuration settings and per function settings. Your will be full of boilerplate code and comments. Feel free to delete it all and paste this in. serverless.yml serverless.yml The property lists all the functions in the service. We will only need one function because it will run the Nuxt rendering. It works by spinning up a tiny Express app, connecting the Nuxt renderer middleware to the Express router and passing the app to the module. In turn, this will bundle the whole Express app into a single lambda function and tie it to an API Gateway endpoint. Under the functions property, you can see a function that will have a handler named in the file. API Gateway will proxy any and every request to the internal Express router which will tell the Nuxt renderer to render our Vue.js pages. Woah, that sounds complicated! But it's really not. Once we start writing the code you'll see how simple it really is. functions serverless-http nuxt nuxt index.js We’ve also added two plugins, the for letting more mime types pass through API Gateway and the which lets us hook up domain names to our endpoints effortlessly. serverless-apigw-binary serverless-domain-manager We also have a section at the bottom. The property acts as a way to safely load environment variables into our service. They're later referenced by using where the actual values are kept in a simple file called . custom secrets ${self:custom.secrets.<environment_var>} secrets.json Apart from that, we’re also letting the API Gateway binary plugin know we want to let all types through, and setting a custom domain for our endpoint. That’s it for the configuration, let’s add the file. secrets.json 5. Add the secrets file We all know pushing private keys to GitHub kills baby penguins. Let’s not do that. Handling this with the Serverless Framework is simple. Add a file and paste this in. secrets.json Now, only by changing these values you can deploy different environments to different stages and domains. Pretty cool. Build the app with the Serverless Framework and Nuxt.js We’ll use Nuxt.js to build our universal Vue.js app. What does this mean? Well, let’s keep it simple, it’s just a server-side rendered single page application. Meaning you don’t need to worry about SEO because it’ll render the JavaScript before sending it to the client. But, once it’s loaded in on the client side, it won’t ask for the file again, and cache it instead. More speed! I love it. Let’s jump in. 1. Setting up the Nuxt.js server(less)-side rendering For Nuxt to work at all we need a file to add our build configuration. nuxt.config.js You can see we required the file in order to load our stage in the URL to the static files. You'll see why this is important once we add the route in the Express router below. Also, check the , it specifies the name of the folder where our client-side files are located. secrets.js publicPath srcDir Once this is added, create another file named . Really intuitive, I know. nuxt.js This is pretty straightforward. We’re grabbing Express and Nuxt, creating a static route with and passing it the directory of the bundled JavaScript that Nuxt will create. Here the path is but because API Gateway adds the stage as a postfix, we needed to specify it in the in the above mentioned file. express.static /_nuxt publicPath nuxt.config.js Once the configuration is loaded, there’s nothing left to do except pass the middleware to the Express app. nuxt.render Now, the app needs to be hooked up to and exported as a lambda function. Create an file and paste this in. serverless-http index.js As you can see we also need to create file to hold all the mime types we want to enable. It'll just a simple array which we pass into the module. binaryMimeTypes.js serverless-http Sweet, that’s it regarding the Nuxt setup. Let’s jump into the client-side code! 2. Writing client-side Vue.js In the root of your project create a new folder and name it . If you scroll up we set the in the file to point to a directory named . client srcDir nuxt.config.js client In this folder, create three more folders named, , , . Once inside folder, create a new file with the name , and paste this in. client components layouts pages layouts default.vue The default view will have the component and the component with rendered content from Nuxt. <navbar/> <nuxt/> Now add the file in the folder. navbar.vue components This is an incredibly simple navigation that’ll be used to navigate between some cute dogs. It’ll make sense once we add something to the folder. pages In the folder create an file and add the code below. pages index.vue The file will be rendered on the root path of our app. It calls a dog API and will show a picture of a cute dog. To create more routes, create a sub-folder called and create an file and a file in there. The will be rendered at the route while the will be rendered at where the represents a route parameter. index.vue dogs index.vue _breed.vue index.vue /dogs _breed.vue /dogs/:breed :breed Add this to the in the directory. index.vue dogs And, another snippet in the file in the folder. _breed.vue dogs As you can see in these files there’s a function. It will add custom fields in the of your page, giving it proper SEO support! head() <head> Note : If you’re stuck, here’s what the code looks like in the repo . Let’s deploy it and see if it works. Deploy the app to AWS Lambda At the very beginning, we added a script to our called . It'll build the Nuxt app and deploy the serverless service as we specified in the . package.json deploy serverless.yml All you need to do is run: $ npm run deploy You’ll see the terminal return some output with the endpoint for your app. But, there’s one more thing for us to do. We need to add the domain. We’ve already added the configuration in the but there's one more command we need to run. serverless.yml $ sls create_domain This will create a CloudFront distribution and hook it up to your domain. Make sure that you’ve added the certificates to your AWS account. It usually takes around 20 minutes for AWS to provision a new distribution. Go have a coffee. $ npm run deploy Back? Okay, go ahead and deploy it all once again. You’ll still be able to use the default endpoints, but now you also have it tied up to your domain. Here’s what it should look like. Sweet, your app is up-and-running. Go ahead and try it out. Test the app with Dashbird I usually look at my Dashbird metrics while testing an app to make sure it all works as expected. If it does, there shouldn’t be any errors in the browser console, nor in the Dashbird app. What’s cool is that is to . That’s a win-win by my book. Dashbird free, and doesn’t require a credit card sign up The logs on my end are showing all green, so it’s working perfectly! That’s in, the app is done. You’ve created a server-side rendered Vue.js app with Nuxt.js, hosted it in a serverless environment on AWS Lambda, and added a way to monitor and debug your app before your users start complaining. Doesn’t get any better than that. Wrapping up This is a whole new way of thinking about creating fast and responsive websites. There are absolutely no servers you need to worry about. Just deploy the code and rest assured it’ll work. If something breaks, you have watching your back, alerting you in Slack if something is wrong. Damn, I love Slack integrations. Dashbird If you got stuck anywhere take a look at the for further reference, and feel free to give it a star if you want more people to see it on GitHub. GitHub repo If you want to read some of my previous serverless musings head over to or my profile join my newsletter! Or, take a look at a few of my articles right away: Building a serverless contact form with AWS Lambda and AWS SES A crash course on Serverless APIs with Express and MongoDB Solving invisible scaling issues with Serverless and MongoDB How to deploy a Node.js application to AWS Lambda using Serverless Getting started with AWS Lambda and Node.js A crash course on securing Serverless APIs with JSON web tokens Migrating your Node.js REST API to Serverless Building a Serverless REST API with Node.js and MongoDB A crash course on Serverless with Node.js I also highly recommend checking out about Nuxt.js, and about the serverless domain manager. this article this tutorial Hope you guys and girls enjoyed reading this as much as I enjoyed writing it. If you liked it, slap that tiny heart so more people here on Medium will see this tutorial. Until next time, be curious and have fun. Originally published at dev.to .