How to submit forms on a static website with VueJS and Netlify functions

Marc Mintel
4 min readSep 12, 2018

--

I have already shared my setup to develop static websites with VueJS, DatoCMS and GraphQL. I recommend you read this first if you didn’t already!

This time I want to explain how you could submit forms, like a contact form, on that serverless architecture.

Please notice: this article uses Netlify functions and requires you to host your webiste on Netlify, even though, the described solutions might also work with AWS Lambda directly, because Netlify uses that internally. However I don’t have any experience with AWS Lambda itself.

TL:DR;

  • Install thenetlify-lambda package
  • Add the scripts netlify-lambda serve lambdaand netlify-lambda build lambdato your npm config
  • Create a netlify.toml with the right path to your functions
  • Add the functions path as a functionsenvironment variable to your nuxt config
  • Create your function as a JavaScript file in your ./lambda folder, e.g. ./lambda/mail.js
  • Export a handler method which receives event , context and callback
  • Make an AJAX call to process.env.functions+"/mail.js" in your Vue Component to call the function

Why Netlify functions?

If you created your website like I described in the article mentioned above you will likely want to have static website, which has several benefit. But one of their downsides is processing user data, because there is no server behind. So many people will probably just use a mailto link to receive emails. Well this might work for some point, but that way you can’t really process those data. It’s hard to collect them, change their status and whatsoever. So without a server we can’t process data. Period.

So, at least for me, the main reason I want to develop static websites is simply because I don’t want to manage a server on my own. And here comes Netlify Functions! Those give you the opportunity to create server side code using JavaScript functions which is absolutely everything we need. While Netlify Functions would really work out of the box there is some setup required to test them locally.

Setting up Netlify Functions

Netlify has a great tutorial on this over here: https://www.netlify.com/docs/functions/#tools-for-building-javascript-functions. But I will go through this briefly.

The package

First install the netlify-lambda npm package via npm install netlify-lambda --save . At the time of writing this article I am using the 0.4.0 version of the package.

The scripts

Then add the commands to your npm scripts like so:

"scripts": {
"build": "nuxt build",
"lint": "eslint --ext .js,.vue --ignore-path .gitignore .",
"dev": "NODE_ENV=development nuxt & yarn functions:serve",
"start": "nuxt start",
"generate": "NODE_ENV=production nuxt generate && yarn functions:build",
"functions:serve": "netlify-lambda serve lambda",
"functions:build": "netlify-lambda build lambda",
"precommit": "npm run lint"
},

The important parts are functions:serve to run a dev server of the functions and functions:build to prepare them for production. The lambdain that line is source folder of your functions. Also notice: on the line "dev": "NODE_ENV=development nuxt & yarn functions:serve" I am starting the nuxt and the functions dev server in parallel.

The config

To make everything work we need to define where those functions will be found. Simply create a netlify.toml and add those lines:

[build]
command = "yarn generate"
publish = "dist"
functions = "/.netlify/functions"

The publish directory is dist because that’s the default when you create a static site with nuxt generate. The path to functions describes the path when building your functions.

Also you should add the url of your functions to the nuxt.config.js to use the correct paths on development or production:

env: {
functions: config.env === 'production' ? `${config.url}/.netlify/functions` : 'http://localhost:9000',
},

Creating a function

To create a function you must simply create a file in your lambda folder, e.g. lambda/mail.js . Each functions must expose a handler method which will receive three arguments event , context and callback .

exports.handler = function(event, context, callback) {
}

The event contains any information about the event that triggered the function. In our case we simply need the event.body which we can parse as JSON via JSON.parse(event.body) . The context contains any information about the context the function was called, like user information. The callback is used to send a respond, like success or error messages.

Creating a mail function

I guess one of the most use cases for functions on static websites are the submission of emails. To submit an email we will also need a mail server, for this I am using Postmark, but you could also use Sendgrid, Mailgun or even your own mail server. To use Postmark we will first install their Node package via npm install postmark --save . Then create the lambda/mail.js file and add the following lines:

I commented the important lines in the code, I hope that’s enough for understanding everything, otherwise just let me know.

Calling the function in VueJS

To use the function you basically just have to make an Ajax call to your function and pass the right parameters. You can see an example of that in the code below. Pay special attention to the submitToServer method! It’s using the fetch API to make an Ajax call, will then use the data of the Vue component via JSON.stringify(this.contactForm) and return the response as a Promise so you can use this in the handleSubmit method.

That’s it!

If you liked please leave a clap for me! Also feel free to comment and share :)

--

--