RedwoodJS – Bringing full-stack to the JAMstack

Update 2020.06.09: here’s a full tutorial to get you started with RedwoodJS.

Now here’s an interesting project:

Redwood is an opinionated, full-stack, serverless web application framework that will allow you to build and deploy JAMstack applications with ease. Imagine a React frontend, statically delivered by CDN, that talks via GraphQL to your backend running on AWS Lambdas around the world, all deployable with just a git push — that’s Redwood.

I’m seeing a similar move as with Rome here: it’s very opiniated.

By making a lot of decisions for you, Redwood lets you get to work on what makes your application special, instead of wasting cycles choosing and re-choosing various technologies and configurations.

Projects built with RedwoodJS exist of two parts (which they call “sides”), both contained in one repo: a web side (built using React) and an api side (which is an implementation of a GraphQL API).

This Twitter thread by the author sheds some more light onto the project (which some compare to Rails when it first got released):

There’s already some videos on how to get started with RedwoodJS available on Egghead that you can check out. It’s not complete, but the 4 ones currently online should get you going on the web side of it.

RedwoodJS →
RedwoodJS Source (GitHub) →

Buiding a JAMstack API with Netlify Functions and Zapier Webhooks

In this tutorial, I’ll show you how to set up webhooks by Zapier to send information to a third-party service and how to integrate them into your JAMstack site using Netlify Functions. This combination allows you to quickly and easily create dynamic functionality on your JAMstack site and create services that do things existing APIs may not even support.

The Cloud Function will call the Zapier webhook, and the webhook – a paid feature of Zapier – is set up to perform an insertion of the data into a Google Spreadsheet.

const axios = require('axios');

exports.handler = async (event, context, callback) => {
  try {
    if(!event.body) {
        return { 
            statusCode: 500, 
            body: 'Name and email are required.'
        };
    }

    const body = JSON.parse(event.body);
    const email = body.email;
    const fullName = body.fullName;
    if(!email) {
        return { 
            statusCode: 500, 
            body: 'email parameter required' 
        };
    }
    if(!fullName) {
        return { 
            statusCode: 500, 
            body: 'name parameter required' 
        };
    }

    return axios({
      method: 'post',
      url: 'https://hooks.zapier.com/hooks/catch/2422393/otw0s6l/',
      data:{
            'email':email,
            'fullName':fullName
      }
    }).then(res => {
      console.log(res);
      return {
        statusCode:200, 
        body: JSON.stringify(res.data)
      }
    })
    .catch(err => {
      return { statusCode: 200, body: JSON.stringify(err.response.data.errors[0]) };
    });

  } catch (err) {[]
    return { statusCode: 500, body: err.toString() };
  }

};

JAMstack API with Netlify Functions and Zapier Webhooks, Part 1 →
Project Code (GitHub) →

How to deploy your first site onto Netlify (+ basic configuration)

About two months ago I developed the website for vBridge, a new company I’m participating in. As the website consists of only one static placeholder-like page, I decided to look into hosting the page directly onto a CDN. Having heard a lot of good things about Netlify, I decided to check that out.

The site itself is built from its source through Webpack by calling yarn build. Where I’d normally go for an external build service to build the site for me, and then deploy it from there into a bucket onto Google Cloud Storage or Amazon S3, Netlify allows me to remove this extra service in between as it has built-in support to building the source for me:

And best of all? Netlify is free (for basic sites), and supports Lambda Functions, and is configurable through a file named netlify.toml.

Configuring Netlify trough netlify.toml

Before adding the site to Netlify itself, I added an instruction file named netlify.toml in the root of the repo. This file tells Netlify what the build command is, which folder needs to be deployed, which redirects to perform, etc.

Here’s the full contents of my netlify.toml configuration file:

[build]
  publish = "build"
  command = "yarn build"

[[redirects]]
  from = "https://vbridge.netlify.com/*"
  to = "https://www.vbridge.eu/:splat"
  status = 301
  force = true

[[headers]]
  for = "/*"
  [headers.values]
    X-Frame-Options = "DENY"
    X-XSS-Protection = "1; mode=block"
    Referrer-Policy = "no-referrer"
    X-Content-Type-Options = "nosniff"
    Strict-Transport-Security = "max-age=63072000; includeSubDomains; preload"

Let’s break that down into several pieces:

  1. [build]
      publish = "build"
      command = "yarn build"

    This snippet tells Netlify what the build command is (yarn build), and which folder that needs to be deployed (build).

  2. [[redirects]]
      from = "https://projectname.netlify.com/*"
      to = "https://www.domain.tld/:splat"
      status = 301
      force = true

    Whenever you deploy a project to Netlify, it will deploy it to a projectname.netlify.com subdomain. To prevent people from accessing the site through that subdomain, add this redirect instruction to your netlify.toml. The snippet is smart enough to retain the value of the pathname when redirecting

  3. Additionally I also added some extra security headers. They are applied to all URLs ("/*")

    [[headers]]
      for = "/*"
      [headers.values]
        X-Frame-Options = "DENY"
        X-XSS-Protection = "1; mode=block"
        Referrer-Policy = "no-referrer"
        X-Content-Type-Options = "nosniff"
        Strict-Transport-Security = "max-age=63072000; includeSubDomains; preload"

Further steps

After having added the netlify.toml into the repo, one still needs to:

  1. Add the project to Netlify itself (see the video above)
    • As your own domain is not pointing to Netlify yet, you might want to skip on that [[redirect]] part in your netlify.toml for now …
  2. Update DNS so that your own domain points to the Netlify servers (ref)
    • Add/change CNAME record for www and point it to projectname.netlify.com.
    • Set A record to 104.198.14.52, or if your DNS provider supports CNAME Flattening, ANAME, or ALIAS, alias the root domain to projectname.netlify.com.
  3. Once DNS has propagated, Netlify will automatically enable HTTPS for your site: Netlify will automatically redirect non-https and non-www visits to https://www.domain.tld/
    • The Strict-Transport-Security header in my netlify.toml is a recommended extra on top of this, intended for browsers. By adding this, browsers will immediately request the site over HTTPS, even when the user types in http://… first. See MDN’s page on HSTS for more info.

And oh, if you want to create your own 404 page, just build a file named 404.html and it will be used as the 404 page 🙂

Did this help you out? Like what you see?
Thank me with a coffee.

I don't do this for profit but a small one-time donation would surely put a smile on my face. Thanks!

☕️ Buy me a Coffee (€3)

To stay in the loop you can follow @bramus or follow @bramusblog on Twitter.

An introduction to the JAMstack

This introduction to JAMstack – or is it SHAMstack? – is quite complete:

Traditional websites or CMS sites (e.g WordPress, Drupal, etc.) rely heavily on servers, plugins and databases. But the JAMstack can load some JavaScript that receives data from an API, serving files from a CDN and markup generated using a static site generator during deploy time.

Maggie Appleton – from the aforementioned illustrated.dev – also created this ace drawing:

☝️ Yes, that should be markup instead of markdown, I already notified Maggie about it 😉

And oh, I follow Chris here, whether <body><script src="react-bundle.js"></script></body> (technically) falls under the JAMstack label or not:

An introduction to the JAMstack: the architecture of the modern web →