From 709d80b9985c0a02c48abb911a1ada93034542fe Mon Sep 17 00:00:00 2001 From: Alexander zur Bonsen Date: Fri, 16 May 2025 10:37:01 +0200 Subject: [PATCH 01/12] chore: clarify the definition of dataReloadRatio The SWD model defines the dataCacheRatio which is the complement of the dataReloadRatio, i.e. 1 - dataCacheRatio. Clarify that in the description. Signed-off-by: Alexander zur Bonsen --- src/docs/co2js/methods.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/docs/co2js/methods.md b/src/docs/co2js/methods.md index e20d85f..8b00154 100644 --- a/src/docs/co2js/methods.md +++ b/src/docs/co2js/methods.md @@ -134,7 +134,7 @@ The `perVisitTrace()` function accepts the following parameters: The `options` parameter can contain any of the following keys. These can be used to adjust the values used by the Sustainable Web Design Model's calculation. -- `dataReloadRatio` Optional – a `number` between 0 and 1 representing the percentage of data that is downloaded by return visitors. +- `dataReloadRatio` Optional – a `number` between 0 and 1 representing the percentage of data that is downloaded by return visitors. This is the complement of the data cache ratio from the Sustainable Web Design model, i.e. dataReloadRatio = 1 - dataCacheRatio. - `firstVisitPercentage` Optional – a `number` between 0 and 1 representing the percentage of new visitors. - `returnVisitPercentage` Optional – a `number` between 0 and 1 representing the percentage of returning visitors. - `greenHostingFactor`
Sustainable Web Design Model v4 only
- The portion of hosting services powered by renewable or zero-carbon energy, between 0 and 1. If the `green hosting` boolean above is set to `true` then the `greenHostingFactor` will always be `1`. @@ -173,6 +173,6 @@ The `perVisitTrace()` function returns an object with the following keys: - `dataCenter` – A `number` representing the carbon intensity for this segment (in grams per kilowatt-hour) used in the calculation. - `networks` – A `number` representing the carbon intensity for this segment (in grams per kilowatt-hour) used in the calculation. - `production` - A `number` representing the carbon intensity for this segment (in grams per kilowatt-hour) used in the calculation. - - `dataReloadRatio` – a `number` between 0 and 1 representing the percentage of data that is downloaded by return visitors. + - `dataReloadRatio` – a `number` between 0 and 1 representing the percentage of data that is downloaded by return visitors. This is the complement of the data cache ratio from the Sustainable Web Design model, i.e. dataReloadRatio = 1 - dataCacheRatio. - `firstVisitPercentage` – a `number` between 0 and 1 representing the percentage of new visitors. - `returnVisitPercentage` – a `number` between 0 and 1 representing the percentage of returning visitors. From 68b99783ac24da9d028fcdb064c34a7d94e1ed15 Mon Sep 17 00:00:00 2001 From: fershad <27988517+fershad@users.noreply.github.com> Date: Tue, 3 Jun 2025 16:35:20 +0800 Subject: [PATCH 02/12] add redirects for carbon.txt 404 --- public/_redirects | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 public/_redirects diff --git a/public/_redirects b/public/_redirects new file mode 100644 index 0000000..4f6cb4a --- /dev/null +++ b/public/_redirects @@ -0,0 +1,2 @@ +/carbon.txt /carbon.txt 404 +/.well-known/carbon.txt /.well-known/carbon.txt 404 From f7c2ffd863af23b333f2b1c62737e2288376e317 Mon Sep 17 00:00:00 2001 From: fershad <27988517+fershad@users.noreply.github.com> Date: Tue, 3 Jun 2025 16:40:53 +0800 Subject: [PATCH 03/12] Update _redirects --- public/_redirects | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/public/_redirects b/public/_redirects index 4f6cb4a..718072d 100644 --- a/public/_redirects +++ b/public/_redirects @@ -1,2 +1,2 @@ -/carbon.txt /carbon.txt 404 -/.well-known/carbon.txt /.well-known/carbon.txt 404 +/carbon.txt / 404 +/.well-known/carbon.txt / 404 From 0c48e2f7cbab719ed58c5f27c50d1955f58633fd Mon Sep 17 00:00:00 2001 From: Bertrand Keller Date: Thu, 5 Jun 2025 13:28:04 +0200 Subject: [PATCH 04/12] Update carbon-txt-validator-architecture.md Typofix --- .../carbon-txt/explainer/carbon-txt-validator-architecture.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/docs/carbon-txt/explainer/carbon-txt-validator-architecture.md b/src/docs/carbon-txt/explainer/carbon-txt-validator-architecture.md index ec2d10d..9cd4cc4 100644 --- a/src/docs/carbon-txt/explainer/carbon-txt-validator-architecture.md +++ b/src/docs/carbon-txt/explainer/carbon-txt-validator-architecture.md @@ -29,7 +29,7 @@ The following diagrams use the [C4 model](https://c4model.com/) for describing s ![Context - a user sends a domain to lookup to the carbon.txt validator, which then fetches the carbon.txt file from that domain. The validator sends back validation results to the user.](https://carbon-txt-validator.readthedocs.io/en/latest/_images/1-a-context.jpg) -The context view demonstrate how we expect the the validator to be used by end-users. +The context view demonstrate how we expect the validator to be used by end-users. These might be people using the validator via the [carbon.txt website](https://carbontxt.org/tools/validator), as command line tool, or in a data pipeline, @@ -86,4 +86,4 @@ So, for a CSRD report that is written to fit pre-agreed standards, like being wr The In our CSRD Processor uses [Arelle](https://arelle.readthedocs.io/), an open source library for working with XBRL documents, to turn XBRL-formatted CSRD reports into datastructures that can be manipulated in Python, and that can be checked for the existence of specific data points. -The validation results are returned in API respones, or the output in CLI commands. +The validation results are returned in API responses, or the output in CLI commands. From b7b751c7cff7864278abf2a5681501d899bdf30d Mon Sep 17 00:00:00 2001 From: fershad <27988517+fershad@users.noreply.github.com> Date: Wed, 18 Jun 2025 16:45:46 +0800 Subject: [PATCH 05/12] fix horizontal scroll for table --- .../grid-aware-tutorial-cloudflare-workers.md | 106 +++++- src/styles/index.css | 359 +++++++++--------- 2 files changed, 275 insertions(+), 190 deletions(-) diff --git a/src/docs/grid-aware-websites/tutorials/grid-aware-tutorial-cloudflare-workers.md b/src/docs/grid-aware-websites/tutorials/grid-aware-tutorial-cloudflare-workers.md index 92c7353..9665558 100644 --- a/src/docs/grid-aware-websites/tutorials/grid-aware-tutorial-cloudflare-workers.md +++ b/src/docs/grid-aware-websites/tutorials/grid-aware-tutorial-cloudflare-workers.md @@ -123,19 +123,99 @@ export default { The worker we have setup will run on our assigned route, but it will just return the original page regardless of the results of the grid-aware checks that it runs. The `gridAwareAuto` function accepts an options object as the fourth parameter. This allows for some configuration to be made to the implementation. Accepted options values are: -| Option | Type | Default | Possible values | Description | -| ----------------- | ------------ | -------------------- | ------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| `contentType` | String[] | `['text/html']` | Example: ['text/html', 'text/css'] | Defines the content types that should be processed | -| `ignoreRoutes` | String[] | `[]` | Example: ['/wp-admin', '/assets/js'] | A list of routes where grid-aware code should not be applied | -| `ignoreGawCookie` | String | `'gaw-ignore'` | "gaw-ignore" | A cookie that when present will result in grid-aware code being skipped | -| `locationType` | String | `'country'` | "country", "latlon" | Indicates the geolocation data to use for grid-aware checks. | -| `htmlChanges` | HTMLRewriter | `null` | See code example below | HTMLRewriter functions which can be used to make adjustments to the page when grid-aware changes need to be appplied. | -| `gawDataSource` | String | `'electricity maps'` | "electricity maps" | The data source to use from the core [Grid-aware Websites](https://github.com/thegreenwebfoundation/grid-aware-websites?tab=readme-ov-file#working-with-this-library) library. | -| `gawDataApiKey` | String | `''` | "xyz123" | The API key (if any) for the chosen data source. | -| `gawDataType` | String | `'power'` | "power", "carbon" | The data type to use from the core Grid-aware Websites library. | -| `kvCacheData` | Boolean | `false` | true, false | Indicate if grid data from the API should be cached in Cloudflare Workers KV for one hour. Read [setup instructions](#cache-grid-data-in-cloudflare-workers-kv). | -| `kvCachePage` | Boolean | `false` | true, false | Indicates if the modified grid-aware page should be cached in Cloudflare Workers KV for 24 hours. Read [setup instructions](#cache-grid-data-in-cloudflare-workers-kv) | -| `debug` | String | "none" | "none", "full", "headers", "logs" | Activates debug mode which outputs logs and returns additional response headers. | +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Configuration options for the gridAwareAuto function
OptionTypeDefaultPossible valuesDescription
contentTypeString[]['text/html']Example: ['text/html', 'text/css']Defines the content types that should be processed
ignoreRoutesString[][]Example: ['/wp-admin', '/assets/js']A list of routes where grid-aware code should not be applied
ignoreGawCookieString'gaw-ignore'"gaw-ignore"A cookie that when present will result in grid-aware code being skipped
locationTypeString'country'"country", "latlon"Indicates the geolocation data to use for grid-aware checks.
htmlChangesHTMLRewriternullSee code example belowHTMLRewriter functions which can be used to make adjustments to the page when grid-aware changes need to be appplied.
gawDataSourceString'electricity maps'"electricity maps"The data source to use from the core Grid-aware Websites library.
gawDataApiKeyString''"xyz123"The API key (if any) for the chosen data source.
gawDataTypeString'power'"power", "carbon"The data type to use from the core Grid-aware Websites library.
kvCacheDataBooleanfalsetrue, falseIndicate if grid data from the API should be cached in Cloudflare Workers KV for one hour.
kvCachePageBooleanfalsetrue, falseIndicates if the modified grid-aware page should be cached in Cloudflare Workers KV for 24 hours.
debugString"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. diff --git a/src/styles/index.css b/src/styles/index.css index 7cffedd..d5f90a7 100644 --- a/src/styles/index.css +++ b/src/styles/index.css @@ -3,28 +3,28 @@ @tailwind utilities; .menu .menu-title { - opacity: 1; + opacity: 1; } .menu .menu-title > * { } .footer .footer-title { - /* @apply text-white; */ - opacity: 1; + /* @apply text-white; */ + opacity: 1; } .collapse:focus-within:not(.collapse-close) .collapse-content { - max-height: 9000px; + max-height: 9000px; } .collapse-arrow:focus-within:not(.collapse-close) .collapse-title:after { - transform: rotate(225deg); + transform: rotate(225deg); } .collapse:focus:not(.collapse-close) .collapse-title .collapse-title-text, .collapse:focus-within:not(.collapse-close) - .collapse-title - .collapse-title-text { - font-weight: 700; + .collapse-title + .collapse-title-text { + font-weight: 700; } h2[id], @@ -32,16 +32,16 @@ h3[id], h4[id], h5[id], h6[id] { - display: flex; - flex-wrap: wrap; - align-items: center; - gap: 0.75rem; - scroll-margin-block-start: 1rem; + display: flex; + flex-wrap: wrap; + align-items: center; + gap: 0.75rem; + scroll-margin-block-start: 1rem; } .header-anchor { - display: grid; - place-items: center; + display: grid; + place-items: center; } h2[id] > .header-anchor > span, @@ -49,8 +49,8 @@ h3[id] > .header-anchor > span, h4[id] > .header-anchor > span, h5[id] > .header-anchor > span, h6[id] > .header-anchor > span { - opacity: 0.25; - display: inline-block; + opacity: 0.25; + display: inline-block; } h2[id]:hover span, @@ -58,7 +58,7 @@ h3[id]:hover span, h4[id]:hover span, h5[id]:hover span, h6[id]:hover span { - opacity: 1; + opacity: 1; } /** @@ -70,64 +70,64 @@ h6[id]:hover span { code[class*="language-"], pre[class*="language-"], code:not([class]) { - color: #f8f8f2; - background: none; - font-family: Consolas, Monaco, "Andale Mono", "Ubuntu Mono", monospace; - text-align: left; - white-space: pre; - word-spacing: normal; - word-break: normal; - word-wrap: normal; - line-height: 1.5; - font-size: inherit; - - -moz-tab-size: 4; - -o-tab-size: 4; - tab-size: 4; - - -webkit-hyphens: none; - -moz-hyphens: none; - -ms-hyphens: none; - hyphens: none; + color: #f8f8f2; + background: none; + font-family: Consolas, Monaco, "Andale Mono", "Ubuntu Mono", monospace; + text-align: left; + white-space: pre; + word-spacing: normal; + word-break: normal; + word-wrap: normal; + line-height: 1.5; + font-size: inherit; + + -moz-tab-size: 4; + -o-tab-size: 4; + tab-size: 4; + + -webkit-hyphens: none; + -moz-hyphens: none; + -ms-hyphens: none; + hyphens: none; } /* Code blocks */ pre[class*="language-"] { - padding: 1em; - margin: 0.5em 0; - overflow: auto; - border-radius: 0.3em; + padding: 1em; + margin: 0.5em 0; + overflow: auto; + border-radius: 0.3em; } :not(pre) > code[class*="language-"], pre[class*="language-"] { - background: #2b2b2b; + background: #2b2b2b; } /* Inline code */ :not(pre) > code[class*="language-"] { - padding: 0.3em 0.4em; - border-radius: 0.3em; - white-space: normal; + padding: 0.3em 0.4em; + border-radius: 0.3em; + white-space: normal; } code:not([class]) { - padding: 0.15rem; - border-radius: 0.1em; - white-space: normal; - @apply bg-zinc-200; - color: #2b2b2b; + padding: 0.15rem; + border-radius: 0.1em; + white-space: normal; + @apply bg-zinc-200; + color: #2b2b2b; } .token.comment, .token.prolog, .token.doctype, .token.cdata { - color: #d4d0ab; + color: #d4d0ab; } .token.punctuation { - color: #fefefe; + color: #fefefe; } .token.property, @@ -135,12 +135,12 @@ code:not([class]) { .token.constant, .token.symbol, .token.deleted { - color: #ffa07a; + color: #ffa07a; } .token.boolean, .token.number { - color: #00e0e0; + color: #00e0e0; } .token.selector, @@ -149,7 +149,7 @@ code:not([class]) { .token.char, .token.builtin, .token.inserted { - color: #abe338; + color: #abe338; } .token.operator, @@ -158,201 +158,206 @@ code:not([class]) { .language-css .token.string, .style .token.string, .token.variable { - color: #00e0e0; + color: #00e0e0; } .token.atrule, .token.attr-value, .token.function { - color: #ffd700; + color: #ffd700; } .token.keyword { - color: #00e0e0; + color: #00e0e0; } .token.regex, .token.important { - color: #ffd700; + color: #ffd700; } .token.important, .token.bold { - font-weight: bold; + font-weight: bold; } .token.italic { - font-style: italic; + font-style: italic; } .token.entity { - cursor: help; + cursor: help; } @media screen and (-ms-high-contrast: active) { - code[class*="language-"], - pre[class*="language-"] { - color: windowText; - background: window; - } - - :not(pre) > code[class*="language-"], - pre[class*="language-"] { - background: window; - } - - .token.important { - background: highlight; - color: window; - font-weight: normal; - } - - .token.atrule, - .token.attr-value, - .token.function, - .token.keyword, - .token.operator, - .token.selector { - font-weight: bold; - } - - .token.attr-value, - .token.comment, - .token.doctype, - .token.function, - .token.keyword, - .token.operator, - .token.property, - .token.string { - color: highlight; - } - - .token.attr-value, - .token.url { - font-weight: normal; - } + code[class*="language-"], + pre[class*="language-"] { + color: windowText; + background: window; + } + + :not(pre) > code[class*="language-"], + pre[class*="language-"] { + background: window; + } + + .token.important { + background: highlight; + color: window; + font-weight: normal; + } + + .token.atrule, + .token.attr-value, + .token.function, + .token.keyword, + .token.operator, + .token.selector { + font-weight: bold; + } + + .token.attr-value, + .token.comment, + .token.doctype, + .token.function, + .token.keyword, + .token.operator, + .token.property, + .token.string { + color: highlight; + } + + .token.attr-value, + .token.url { + font-weight: normal; + } } seven-minute-tabs { - display: block; - padding: 0 1rem; - border-radius: 0.5rem; - /* margin: 0 -1rem 1rem; */ - border: 2px solid #111; - padding-bottom: 1rem; + display: block; + padding: 0 1rem; + border-radius: 0.5rem; + /* margin: 0 -1rem 1rem; */ + border: 2px solid #111; + padding-bottom: 1rem; } @media (prefers-color-scheme: dark) { - seven-minute-tabs { - border-color: #555; - } + seven-minute-tabs { + border-color: #555; + } } seven-minute-tabs [role="tablist"] { - list-style: none; - padding: 0 1rem; - margin: 0 -1rem; - font-size: 0.8125em; /* 13px /16 */ - line-height: 1.8; - text-align: left; + list-style: none; + padding: 0 1rem; + margin: 0 -1rem; + font-size: 0.8125em; /* 13px /16 */ + line-height: 1.8; + text-align: left; } seven-minute-tabs [role="tablist"] > * { - display: inline-block; - margin: 0 0.5rem; + display: inline-block; + margin: 0 0.5rem; } seven-minute-tabs [role="tablist"]:first-child { - margin-bottom: 0.5rem; + margin-bottom: 0.5rem; } seven-minute-tabs [role="tablist"]:last-child { - margin-top: 0.5rem; + margin-top: 0.5rem; } seven-minute-tabs [role="tab"] { - display: inline-block; - font-weight: 500; - padding: 0 0.65em; - margin: 0 0.1em; - text-decoration: none; - border-bottom: 5px solid transparent; - padding-top: 0.25rem; + display: inline-block; + font-weight: 500; + padding: 0 0.65em; + margin: 0 0.1em; + text-decoration: none; + border-bottom: 5px solid transparent; + padding-top: 0.25rem; } seven-minute-tabs [role="tab"][aria-selected="true"] { - border-color: hsl(var(--s)); - background-color: hsl(var(--p) / 0.25); - color: hsl(var(--pc)); + border-color: hsl(var(--s)); + background-color: hsl(var(--p) / 0.25); + color: hsl(var(--pc)); } /* Code samples in tabs */ seven-minute-tabs [role="tabpanel"] pre { - border-radius: 0; + border-radius: 0; } seven-minute-tabs [role="tabpanel"] pre:last-child { - margin-bottom: 0; + margin-bottom: 0; } .alert > p { - display: block; + display: block; } .roadmap-issue-contributor img { - display: inline-block; - height: 2.5ch; - border-radius: 50%; - margin-block: 0; + display: inline-block; + height: 2.5ch; + border-radius: 50%; + margin-block: 0; } @layer components { - .alert { - @apply border-4; - } - .alert-info { - @apply bg-info/5 border-info; - } - - .badge { - @apply font-normal; - } - .badge-secondary, - .badge-warning, - .badge-error { - @apply text-white; - } - - .btn { - @apply rounded-full border-0 no-underline font-bold px-5; - } - .btn-lg { - @apply px-7; - } - .btn-primary, - .btn-secondary { - @apply hover:text-white hover:bg-accent; - } - .btn-black { - @apply bg-black text-white; - @apply hover:text-black hover:bg-secondary; - } + .alert { + @apply border-4; + } + .alert-info { + @apply bg-info/5 border-info; + } + + .badge { + @apply font-normal; + } + .badge-secondary, + .badge-warning, + .badge-error { + @apply text-white; + } + + .btn { + @apply rounded-full border-0 no-underline font-bold px-5; + } + .btn-lg { + @apply px-7; + } + .btn-primary, + .btn-secondary { + @apply hover:text-white hover:bg-accent; + } + .btn-black { + @apply bg-black text-white; + @apply hover:text-black hover:bg-secondary; + } } .roadmap-list > li:nth-child(odd) { - @apply bg-neutral-100; - @apply border-y-neutral-300; - @apply border-y; - @apply border-solid; + @apply bg-neutral-100; + @apply border-y-neutral-300; + @apply border-y; + @apply border-solid; } .roadmap-list > li > h3:first-child { - margin-block-start: 1.25rem; + margin-block-start: 1.25rem; } .roadmap-list > li > div:last-child { - margin-block-end: 1.25rem; + margin-block-end: 1.25rem; } .language-toml .table { - display: initial; + display: initial; } aside + aside { - margin-top: 1rem; + margin-top: 1rem; +} + +.table-wrapper { + overflow: auto; + max-width: 100vw; } From b37a7bba476eb3545cd4ccca437d1a80a9c33621 Mon Sep 17 00:00:00 2001 From: fershad <27988517+fershad@users.noreply.github.com> Date: Thu, 10 Jul 2025 23:04:13 +0200 Subject: [PATCH 06/12] Add more config options to cf worker tutorial --- .../grid-aware-tutorial-cloudflare-workers.md | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/docs/grid-aware-websites/tutorials/grid-aware-tutorial-cloudflare-workers.md b/src/docs/grid-aware-websites/tutorials/grid-aware-tutorial-cloudflare-workers.md index 9665558..def6b61 100644 --- a/src/docs/grid-aware-websites/tutorials/grid-aware-tutorial-cloudflare-workers.md +++ b/src/docs/grid-aware-websites/tutorials/grid-aware-tutorial-cloudflare-workers.md @@ -213,6 +213,27 @@ The worker we have setup will run on our assigned route, but it will just return "none", "full", "headers", "logs" Activates debug mode which outputs logs and returns additional response headers. + + dev + Boolean + false + true, false + Enables development mode, which redirects requests to a local development server. + + + devConfig + Object + {} + {hostname: "localhost", port: "8080", protocol: "http"} + Configuration options for the development mode, including hostname, port, and protocol. + + + infoBarTarget + String + '' + Example: "header", "#info-container" + CSS selector for the element where the grid-aware info bar will be inserted. + @@ -227,6 +248,8 @@ export default { return gridAwareAuto(request, env, ctx, { // Use this API key that has been saved as a secret gawDataApiKey: env.EMAPS_API_KEY, + // A CSS selector for the element where the grid-aware info bar will be inserted. + infoBarTarget: "#gaw-info-bar", debug: "full", // Make these changes to the web page using HTMLRewriter htmlChanges: new HTMLRewriter().on("html", { From ed1a8c234e9960b70b655c5d0eb8785fac54d63c Mon Sep 17 00:00:00 2001 From: fershad <27988517+fershad@users.noreply.github.com> Date: Tue, 22 Jul 2025 17:03:50 +0800 Subject: [PATCH 07/12] update config table --- .../grid-aware-tutorial-cloudflare-workers.md | 256 +++++++++++------- 1 file changed, 156 insertions(+), 100 deletions(-) diff --git a/src/docs/grid-aware-websites/tutorials/grid-aware-tutorial-cloudflare-workers.md b/src/docs/grid-aware-websites/tutorials/grid-aware-tutorial-cloudflare-workers.md index def6b61..5c60396 100644 --- a/src/docs/grid-aware-websites/tutorials/grid-aware-tutorial-cloudflare-workers.md +++ b/src/docs/grid-aware-websites/tutorials/grid-aware-tutorial-cloudflare-workers.md @@ -136,105 +136,154 @@ The worker we have setup will run on our assigned route, but it will just return - - contentType - String[] - ['text/html'] - Example: ['text/html', 'text/css'] - Defines the content types that should be processed - - - ignoreRoutes - String[] - [] - Example: ['/wp-admin', '/assets/js'] - A list of routes where grid-aware code should not be applied - - - ignoreGawCookie - String - 'gaw-ignore' - "gaw-ignore" - A cookie that when present will result in grid-aware code being skipped - - - locationType - String - 'country' - "country", "latlon" - Indicates the geolocation data to use for grid-aware checks. - - - htmlChanges - HTMLRewriter - null - See code example below - HTMLRewriter functions which can be used to make adjustments to the page when grid-aware changes need to be appplied. - - - gawDataSource - String - 'electricity maps' - "electricity maps" - The data source to use from the core Grid-aware Websites library. - - - gawDataApiKey - String - '' - "xyz123" - The API key (if any) for the chosen data source. - - - gawDataType - String - 'power' - "power", "carbon" - The data type to use from the core Grid-aware Websites library. - - - kvCacheData - Boolean - false - true, false - Indicate if grid data from the API should be cached in Cloudflare Workers KV for one hour. - - - kvCachePage - Boolean - false - true, false - Indicates if the modified grid-aware page should be cached in Cloudflare Workers KV for 24 hours. - - - debug - String - "none" - "none", "full", "headers", "logs" - Activates debug mode which outputs logs and returns additional response headers. - - - dev - Boolean - false - true, false - Enables development mode, which redirects requests to a local development server. - - - devConfig - Object - {} - {hostname: "localhost", port: "8080", protocol: "http"} - Configuration options for the development mode, including hostname, port, and protocol. - - - infoBarTarget - String - '' - Example: "header", "#info-container" - CSS selector for the element where the grid-aware info bar will be inserted. - - + + contentType + String[] + ['text/html'] + Example: ['text/html', 'text/css'] + Defines the content types that should be processed + + + ignoreRoutes + String[] + [] + Example: ['/wp-admin', '/assets/js'] + A list of routes where grid-aware code should not be applied + + + ignoreGawCookie + String + 'gaw-ignore' + "gaw-ignore" + A cookie that when present will result in grid-aware code being skipped + + + userOptIn + Boolean + false + true, false + Allows developers to specify if users are required to opt-in to the grid-aware website experience + + + locationType + String + 'latlon' + "latlon", "country" + Type of location data to use + + + htmlChanges + Object + {} + {"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 + null + Custom HTMLRewriter for page modification at low grid intensity level + + + + htmlChanges.moderate + HTMLRewriter + null + Custom HTMLRewriter for page modification at moderate grid intensity level + + + + htmlChanges.high + HTMLRewriter + null + Custom HTMLRewriter for page modification at high grid intensity level + + + + defaultView + String/null + null + null, "low", "moderate", "high" + Default view for the grid-aware website experience + + + gawDataApiKey + String + '' + "xyz123" + API key for the data source + + + infoBar + Object + {} + {target: "", version: "latest", learnMoreLink: "#", popoverText: ""} + Configuration for the info bar element + + + infoBar.target + String + '' + Example: "header", "#info-container" + Target element for the info bar + + + infoBar.version + String + 'latest' + "latest", "1.0.0" + Version of the info bar to use + + + infoBar.learnMoreLink + String + '#' + Example: "https://example.com/learn-more" + Link to learn more about the info bar + + + infoBar.popoverText + String + '' + Example: "This website adapts based on carbon intensity" + Provide a custom string of text to be used in the info bar popover element + + + kvCacheData + Boolean + false + true, false + Whether to cache grid data in KV store. Read setup instructions + + + kvCachePage + Boolean + false + true, false + Whether to cache modified pages in KV store. Read setup instructions + + + debug + String + "none" + "none", "full", "headers", "logs" + Activates debug mode which outputs logs and returns additional response headers + + + dev + Boolean + false + true, false + Whether to enable development mode + + + devConfig + Object + {} + {hostname: "localhost", port: "8080", protocol: "http"} + Configuration for development mode + + @@ -249,7 +298,14 @@ export default { // Use this API key that has been saved as a secret gawDataApiKey: env.EMAPS_API_KEY, // A CSS selector for the element where the grid-aware info bar will be inserted. - infoBarTarget: "#gaw-info-bar", + infoBar: { + target: "#gaw-info-bar", + learnMoreLink: + "https://www.thegreenwebfoundation.org/tools/grid-aware-websites/", + version: "latest", + popoverText: + "This website adapts based on your local electricity grid's carbon intensity", + }, debug: "full", // Make these changes to the web page using HTMLRewriter htmlChanges: new HTMLRewriter().on("html", { From b72b2d4d3d4e867cd005c2023aa59f962d740a0b Mon Sep 17 00:00:00 2001 From: fershad <27988517+fershad@users.noreply.github.com> Date: Tue, 22 Jul 2025 17:07:48 +0800 Subject: [PATCH 08/12] add branch case study --- src/_data/caseStudies.js | 64 +++++++++++++++++++++++++++------------- 1 file changed, 43 insertions(+), 21 deletions(-) diff --git a/src/_data/caseStudies.js b/src/_data/caseStudies.js index 7558d21..4f9fde3 100644 --- a/src/_data/caseStudies.js +++ b/src/_data/caseStudies.js @@ -1,29 +1,51 @@ -const dev = process.env.NODE_ENV !== 'production' +const dev = process.env.NODE_ENV !== "production"; const caseStudies = async () => { - const { devData } = await import('../helpers/dev/caseStudies.js'); + const { devData } = await import("../helpers/dev/caseStudies.js"); - // if (dev) { - // return devData; - // } + // if (dev) { + // return devData; + // } - const co2js = await fetch('https://www.thegreenwebfoundation.org/wp-json/wp/v2/posts?per_page=100&categories=43,34').then(resp => resp.json()).then(data => data.filter(item => item.categories.includes(43) && item.categories.includes(34))) + const co2js = await fetch( + "https://www.thegreenwebfoundation.org/wp-json/wp/v2/posts?per_page=100&categories=43,34", + ) + .then((resp) => resp.json()) + .then((data) => + data.filter( + (item) => item.categories.includes(43) && item.categories.includes(34), + ), + ); - // This is temporary until we've got more case studies. Since they won't all live on our website, we need to figure out a way to get them all in one place. - const gaw = [ - { - featured_media: "https://browser-worker.fershad.workers.dev/?title=Making+this+website+respond+to+your+local+energy+grid&page=https://fershad.com/writing/making-this-website-grid-aware/", - title: { - rendered: "Making this website respond to your local energy grid" - }, - excerpt: { - rendered: "Fershad Irani covers the technical steps I've taken to make this website respond to a visitor's energy grid. It also touches on the design changes that happen as a result, and the performance and energy impacts of those changes." - }, - link: "https://fershad.com/writing/making-this-website-grid-aware/" - } - ] + // This is temporary until we've got more case studies. Since they won't all live on our website, we need to figure out a way to get them all in one place. + const gaw = [ + { + featured_media: + "https://branch.climateaction.tech/wp-content/uploads/2025/07/Branch-in-grid-aware-high-intensity-mode.jpg", + title: { + rendered: "Designing a Grid-Aware Branch", + }, + excerpt: { + rendered: + "Issue 9 of Branch arrives with a fresh site redesign. This new design builds on valuable feedback we’ve received from you, our community, and some brand-new ideas we’ve been exploring as part of Green Web Foundation’s Grid-aware Websites project.", + }, + link: "https://branch.climateaction.tech/issues/issue-9/designing-a-grid-aware-branch/", + }, + { + featured_media: + "https://browser-worker.fershad.workers.dev/?title=Making+this+website+respond+to+your+local+energy+grid&page=https://fershad.com/writing/making-this-website-grid-aware/", + title: { + rendered: "Making this website respond to your local energy grid", + }, + excerpt: { + rendered: + "Fershad Irani covers the technical steps I've taken to make this website respond to a visitor's energy grid. It also touches on the design changes that happen as a result, and the performance and energy impacts of those changes.", + }, + link: "https://fershad.com/writing/making-this-website-grid-aware/", + }, + ]; - return {co2js, gaw}; -} + return { co2js, gaw }; +}; module.exports = caseStudies; From 23c2e39f4609e78b735d31efd6403e4d0bcda702 Mon Sep 17 00:00:00 2001 From: fershad <27988517+fershad@users.noreply.github.com> Date: Wed, 23 Jul 2025 17:01:36 +0800 Subject: [PATCH 09/12] update media --- src/_data/caseStudies.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/_data/caseStudies.js b/src/_data/caseStudies.js index 4f9fde3..bdc993e 100644 --- a/src/_data/caseStudies.js +++ b/src/_data/caseStudies.js @@ -21,7 +21,7 @@ const caseStudies = async () => { const gaw = [ { featured_media: - "https://branch.climateaction.tech/wp-content/uploads/2025/07/Branch-in-grid-aware-high-intensity-mode.jpg", + "https://branch.climateaction.tech/wp-content/uploads/2025/07/Branch-medium-intensity-mode-2048x1206.jpg", title: { rendered: "Designing a Grid-Aware Branch", }, From ff2110ef6bdf6324bcfa4c5ada065096872855ea Mon Sep 17 00:00:00 2001 From: fershad <27988517+fershad@users.noreply.github.com> Date: Thu, 24 Jul 2025 09:09:02 +0800 Subject: [PATCH 10/12] update emaps note --- .../tutorials/grid-aware-tutorial-cloudflare-workers.md | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/docs/grid-aware-websites/tutorials/grid-aware-tutorial-cloudflare-workers.md b/src/docs/grid-aware-websites/tutorials/grid-aware-tutorial-cloudflare-workers.md index 5c60396..9e28a0a 100644 --- a/src/docs/grid-aware-websites/tutorials/grid-aware-tutorial-cloudflare-workers.md +++ b/src/docs/grid-aware-websites/tutorials/grid-aware-tutorial-cloudflare-workers.md @@ -32,7 +32,14 @@ You should have: You should also be aware of the limits and pricing of Cloudflare Workers, available on the [Cloudflare website](https://developers.cloudflare.com/workers/platform/). -{% include 'partials/gaw-emaps-note.njk' %} +