Raphael Ugwu Writer, software engineer, and a lifelong student.

What you need to know about Netlify build plugins

5 min read 1473

For a while, hosting infrastructure and deploying sites was our only option. You deployed your site, bought a URL, and paid a subscription to keep it active. Today, Netlify has successfully improved this with a host of features including cross-framework support, analytics, and serverless functions. One particular feature, which was rolled out recently, is proving to be a game changer.

In this post, we’re going to learn what Netlify build plugins are, what they do, and how you can create one. This tutorial assumes basic knowledge of Netlify and its features – if you’re not familiar with Netlify, you can check this comprehensive guide out.

What’s a Netlify build plugin?

Build plugins let you automate tasks that can be connected to the build process of your projects. For every time your project is deployed, these tasks are asynchronously carried out. You can use build plugins to perform a variety of actions each time your project is deployed, such as making a cryptocurrency donation each time your site deploys or sending notifications to the rest of the team – the possibilities are endless.

There’s a lot of published plugins created by developers that you can add to your project and perform cool stuff on every deploy. To add a plugin to your project, on your Netlify dashboard, navigate to Sites and then select the project on which you want to add the plugin to:

adding netlify plugins

Next, click on the Plugins tab and navigate through the plugin directory, then select the plugin you would like to have on your project:

select plugins

Building your own plugin

Every Netlify build plugin has a “skeletal” structure that is made up of three files:

  • index.js — The entry point for the plugin. This is where you embed the logic that defines your plugin’s actions with any of Netlify’s Hooks such as onPrebuild, onPostbuild , or onEnd
  • manifest.yml — This file handles interactive data. It could be a set of user inputs or information that will be needed whenever a deploy is to be made
  • package.json —  This file handles non-interactive data, it contains things like your plugin’s name, author, and dependencies

Then there’s an additional file, netlify.toml , which will specify the path to your plugin when it’s included in your project. Note that this file is only useful when your plugin hasn’t been published to NPM yet.

We’re going to work on these four files but first, we need to globally install Netlify in our project’s folder. For my project, I will be deploying an e-commerce store demo built with React Hooks. Using our terminal, let’s navigate to our project folder and install Netlify:

# Navigate to your project
cd react-hooks-app

# Install Netlify CLI globally
npm install netlify-cli -g

### OR use Yarn ### 
yarn global add netlify-cli

Next, in our project, we’ll create a folder for our plugin. In your project folder, create a folder in which the contents of your plugin will be stored. Netlify plugins follow a naming convention where plugins are named according to what they do. We’re building a plugin that sends an email to a teammate or boss for each time our app is deployed so we’ll call this netlify-emailplugin:

+ react-hooks-app
   + .netlify
   + build
   + node_modules
   + public
     - index.html
   + src
   + netlify-emailplugin
     - index.js
     - manifest.yml
     - package.json

package.json

Let’s first handle the package.json file where we’ll define our plugin and install any necessary dependencies we’ll need. In your terminal, navigate to your plugin’s folder and run npm init – this will display a couple of question you will need to fill in about your plugin:

{
  "name": "netlify-emailplugin",
  "version": "1.0.0",
  "description": "A Netlify plugin that emails my boss each time I make an update",
  "main": "index.js",
  "devDependencies": {},
  "scripts": {
    "test": "echo \\\"Error: no test specified\\\" && exit 1"
  },
  "repository": {
    "type": "git",
    "url": "git+https://github.com/fullstackmafia/netlify-emailplugin.git"
  },
  "keywords": [
    "netlify",
    "netlify-plugin",
    "build",
    "plugins"
  ],
  "author": "Raphael Ugwu <[email protected]>",
  "license": "MIT",
  "bugs": {
    "url": "https://github.com/fullstackmafia/netlify-emailplugin/issues"
  },
  "homepage": "https://github.com/fullstackmafia/netlify-emailplugin#readme"
}

It’s very important you have netlify and netlify-plugin as keywords to enhance your plugin’s chances of being found whenever it is looked up. For our plugin, we’ll need to include a dependency that fires off email notifications after each deploy. For this purpose, we’ll use Postmark – an awesome email API. First, let’s sign up with Postmark and get a set of API keys:

postmark servers api tokens

Next, we’ll install Postmark as a dependency on our plugin’s folder:

# Navigate to your plugin's folder
cd netlify-emailplugin

# Install Postmark
npm install postmark

### OR use Yarn ###
yarn add postmark

Once this is done, you’ve successfully set up your package.json file.

netlify.toml

Next, in the root folder of our project, we need to create the netlify.toml file where we’ll specify the pathway to our plugin:

[[plugins]]
package = "./netlify-emailplugin"

Because we’re using a local plugin, we need to include Netlify’s local core installer plugin which will assist with enabling any dependencies installed in our package.json file:

 [[plugins]]
 package = "@netlify/plugin-local-install-core"

 [[plugins]]
 package = "./netlify-emailplugin"

manifest.yml

Our manifest.yml file should contain basic information about our plugin. Since this is an email plugin, we’ll include the plugin’s name, sender’s email (my email) and the receiver’s email (my boss’s email):

name: netlify-emailplugin
inputs:
  - name: from
    description: Sender email
    default: [email protected]
  - name: to
    description: Receiver email
    default: [email protected]

Before we build up our index.js file, let’s take a moment to understand Netlify’s build events. Build events let you access different stages of your app’s build process – with them you can decide where exactly you want your plugin to be triggered. Altogether, Netlify has seven build processes:

  • onInit — runs before anything else
  • onPreBuild — runs before build commands are executed
  • onBuild — runs while build commands are being executed
  • onPostBuild — runs after build commands are executed
  • onSuccess — runs once build is completed successfully
  • onError — runs if there is a build error
  • onEnd — runs on build error or success when the build process ends

For our plugin, we’ll use the onEnd build event – so for each time we run a successful build, an email is sent.

index.js

The first step to creating our index.js file is to include any dependency installed earlier in package.json:

var postmark = require("postmark");

Next, we need to include the constants our plugin will be interacting with. In this case, our constants are the sender’s email, receiver’s email, and our Postmark’s API key. To keep this accessible, unique, and yet secure for each user who will be using this plugin, Netlify lets us save these constants in the Build and Deploy section of our project:

Now we can include these constants in our file:

const {
    FROM_EMAIL,
    KEY,
    TO_EMAIL,
 } = process.env

Following best practices, we ought to include some form of error handling in our plugin. To do this, we’ll throw an error for each time our plugin is missing a constant:

if (!FROM_EMAIL) {
  throw new Error('No sender email present')
}
if (!TO_EMAIL) {
  throw new Error('No recipient email present')
}
if (!KEY) {
  throw new Error('No KEY present')
}

Finally, we’ll initiate a Postmark instance that sends our email. We’ll also provide our plugin with the option of accessing the user input in our manifest.yml file:

const client = new postmark.ServerClient(KEY);
const message = 'Hello Boss, we just deployed some bug fixes'
await client.sendEmail({
  From: inputs.from || FROM_EMAIL,
  To: inputs.to || TO_EMAIL,
  Subject: "New Deploy",
  TextBody: message

There! We’re done compiling our index.js file, what’s left is to wrap all our code in a module.exports function so it’s accessible to the rest of our project:

module.exports = {
    onEnd: async ({ inputs }) => {
        if (!FROM_EMAIL) {
            throw new Error('No sender email present')
          }
          if (!TO_EMAIL) {
            throw new Error('No recipient email present')
          }
          if (!KEY) {
            throw new Error('No KEY present')
          }
          const client = new postmark.ServerClient(KEY);
          const message = 'Hello Boss, we just deployed some bug fixes'
          await client.sendEmail({
            From: inputs.from || FROM_EMAIL,
            To: inputs.to || TO_EMAIL,
            Subject: "New Deploy",
            TextBody: message
          })
    },
}

Now we’re set to use our plugin. Update your most recent changes with a Git push and after that, deploy your project on Netlify. You should receive a summary your build went well and that your plugin was used:
build went well

And your boss should receive your email:

deployed email saying "Hello Boss, we just deployed some bug fixes"

Conclusion

Build plugins will unlock so many chances for cross-collaboration. They haven’t been around for very long but they are already going mainstream. You can check out more awesome examples of build plugins made by other developers in this repo. If you’d like to review the source code of this plugin, you can do so here.

Get set up with LogRocket's modern error tracking in minutes:

  1. Visit https://logrocket.com/signup/ to get an app ID
  2. Install LogRocket via npm or script tag. LogRocket.init() must be called client-side, not server-side
  3. $ npm i --save logrocket 

    // Code:

    import LogRocket from 'logrocket';
    LogRocket.init('app/id');
    Add to your HTML:

    <script src="https://cdn.lr-ingest.com/LogRocket.min.js"></script>
    <script>window.LogRocket && window.LogRocket.init('app/id');</script>
  4. (Optional) Install plugins for deeper integrations with your stack:
    • Redux middleware
    • NgRx middleware
    • Vuex plugin
Get started now
Raphael Ugwu Writer, software engineer, and a lifelong student.

Leave a Reply