Using Grid-aware Websites with Netlify Edge Functions allows you to add grid awareness to an existing website that is hosted on, or proxied through, Cloudflare's network.
In this tutorial, you will learn how to:
You should have:
You should also be aware of the limits and pricing of Netlify Edge Functions, available on the Cloudflare website.
To begin using Grid-aware Websites on an existing website through Netlify Edge Functions, we will first need to add them to a Netlify project. To do this, you can create a netlify/edge-functions
folder at the root of your project. The Netlify docs have instructions if you want to save your edge functions in a different location.
Within the netlify/edge-functions
folder, let's create our edge function file. For this demo, we'll call it gaw.js
.
The netlify/edge-functions/gaw.js
file will contain the code the runs whenever our function is invoked.
We can declare the configuration for our edge function from inside the gaw.js
file we've just created. To do this, add the following code to the file:
export const config = {
path: "/*",
onError: "bypass"
}
Here, we have configured the edge function to run on every route of our site. We've also configured the edge function to be skipped in the event that an error is encountered.
The Netlify docs have more information about all the available configuration options for edge functions.
Later in the project, we'll use the Electricity Maps API to get information about the power breakdown of a country's energy grid. For this, you'll need an Electricity Maps API key added to your project. We'll first set this up for our development environment, and later in this tutorial we'll set it up for production.
There are a few ways to add environment variables to a Netlify project. We'll use a local .env
file, and import it using the Netlify CLI. First, create a .env
file in the root of your project if you don't have one already. Add your Electricity Maps API key as follows:
EMAPS_API_KEY="<your_api_key>"
Then, use Netlify CLI to upload the contents of your .env
file to your project.
npx netlify env:import .env
We can now start coding. To begin, we'll add the Netlify Edge Functions specific plugin for Grid-aware Websites to our gaw.js
edge function. To do this, add the following code to the gaw.js
file.
import gridAwareAuto from "https://esm.sh/@greenweb/gaw-plugin-netlify-edge@next";
export default async (request, context) => {
return gridAwareAuto(request, context);
};
This code uses the gridAwareAuto
helper function to take care of setting up and executing the Grid-aware Websites code. We can deploy this code as it is, and it would run in our project. However, when applying Grid-aware Websites to a project you will probably want to configure the grid aware code a bit more.
The gridAwareAuto
function accepts an options object as the third parameter. This allows for some configuration to be made to the implementation. Accepted options values are:
Option | Type | Required | Default | Possible values | Description |
---|---|---|---|---|---|
gawDataApiKey |
String | Required | '' |
"xyz123" | API key for the Electricity Maps |
locationType |
String | Optional | 'latlon' |
"latlon", "country" | Type of location data to use |
contentType |
String[] | Optional | ['text/html'] |
Example: ['text/html', 'text/css'] | Defines the content types that should be processed |
ignoreRoutes |
String[] | Optional | [] |
Example: ['/wp-admin', '/assets/js'] | A list of routes where grid-aware code should not be applied |
ignoreGawCookie |
String | Optional | 'gaw-ignore' |
"gaw-ignore" | A cookie that when present will result in grid-aware code being skipped |
userOptIn |
Boolean | Optional | false |
true, false | Allows developers to specify if users are required to opt-in to the grid-aware website experience |
htmlChanges |
Object | Optional | {} | {"low": HTMLRewriter, "moderate": HTMLRewriter, "high": HTMLRewriter} | An object to capture the different HTML changes that are applied at each different grid intesity level |
htmlChanges.low |
HTMLRewriter | Optional | null | Custom HTMLRewriter for page modification at low grid intensity level | |
htmlChanges.moderate |
HTMLRewriter | Optional | null | Custom HTMLRewriter for page modification at moderate grid intensity level | |
htmlChanges.high |
HTMLRewriter | Optional | null | Custom HTMLRewriter for page modification at high grid intensity level | |
infoBar |
Object | Optional | {} |
{target: "", version: "latest", learnMoreLink: "#", popoverText: "", customViews: ""} |
Configuration for the info bar element |
infoBar.target |
String | Optional | '' |
Example: "header", "#info-container" | Target element for the info bar |
infoBar.version |
String | Optional | 'latest' |
"latest", "1.0.0" | Version of the info bar to use |
infoBar.learnMoreLink |
String | Optional | '#' |
Example: "https://example.com/learn-more" | Link to learn more about the info bar |
infoBar.popoverText |
String | Optional | '' |
Example: "This website adapts based on carbon intensity" | Provide a custom string of text to be used in the info bar popover element |
infoBar.customViews |
String | Optional | '' |
Example: "custom-low,custom-moderate,custom-high" | Custom views for the grid-aware website experience |
defaultView |
String/null | Optional | null |
null, "low", "moderate", "high" | Default view for the grid-aware website experience |
dev |
Boolean | Optional | false |
true, false | Whether to enable development mode |
devConfig |
Object | Optional | {} |
{hostname: "", port: "", protocol: ""} |
Configuration for development mode |
devConfig.hostname |
String | Optional | '' |
Example: "localhost" | Hostname for development mode |
devConfig.port |
String | Optional | '' |
Example: "8080" | Port for development mode |
devConfig.protocol |
String | Optional | '' |
Example: "http" | Protocol for development mode |
debug |
String | Optional | "none" |
"none", "full", "headers", "logs" | Activates debug mode which outputs logs and returns additional response headers |
In this tutorial, we want to make a change to the page which will be applied when the grid-aware checks return a result that indicate the grid is dirtier than normal. The gridAwareAuto
function will perform these checks for us, so we can use the htmlChanges
option to pass it the changes we want applied.
In the example below we will:
debug
to "full" so that we see logs in our console and browser.data-grid-aware="true"
to the <html>
tag when the Electricity Maps API returns a "high" result.To do this, we'll also need to import the HTMLRewriter tool into our project.
import gridAwareAuto from "https://esm.sh/@greenweb/gaw-plugin-netlify-edge@next";
import { HTMLRewriter } from "https://ghuc.cc/worker-tools/html-rewriter/index.ts";
export default async (request, context) => {
return gridAwareAuto(request, context, {
// Ignore these routes
ignoreRoutes: ["/company/", "/profile/"],
// Use this API key that has been saved as a secret
gawDataApiKey: env.EMAPS_API_KEY,
debug: "full",
// Make these changes to the web page using HTMLRewriter when the grid intensity is high.
// All other states (low, moderate) will return the page as normal - no changes applied.
htmlChanges: {
high: new HTMLRewriter().on("html", {
element(element) {
element.setAttribute("data-grid-aware", "true");
},
}),
},
});
};
We can now do a first test of our code to ensure it works as expected before moving on. In your terminal, run the command below:
npx netlify dev
This command will use the Netlify CLI to run a version of your project in the development environment.
When the CLI runs, a browser window should open automatically showing your project. In your terminal, you should see log outputs including information about the grid data that has been used to make perform the grid-aware checks.
In order to test that the changes you have made are working, you'll need some way to test your Edge Function from different locations around the World. Unfortunately, the ability to mock geolocation using the Netlify CLI does not work when used with the Grid-aware Websites code. You can, instead, resort to one or more of the following workarounds:
country
variable, and adjust that to test different locationsWhen you're ready, you can deploy your worker to run on your website for the actual path you've configured.
Now, you can run npx netlify deploy
in your terminal to deploy your Netlify site and edge fuction to production.
If you've deployed Grid-aware Websites to your own site we'd love to hear from you! Share your experience with us using the contact form via our website.