Skip to content

Commit 0f2b09e

Browse files
Merge pull request #24 from workleap/docs/more-docs-435837
docs: First iteration of the getting-started docs
2 parents 2b6536a + 0d8895c commit 0f2b09e

File tree

4 files changed

+78
-49
lines changed

4 files changed

+78
-49
lines changed

docs/available-options.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,11 @@ icon: gear
88

99
TBD
1010

11-
## `basicAuthPasswordEnvironmentVariableName`
11+
## `cookieName`
1212

1313
TBD
1414

15-
## `cookieName`
15+
## `cookiePath`
1616

1717
TBD
1818

docs/getting-started.md

Lines changed: 76 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -5,25 +5,30 @@ icon: rocket
55

66
# Getting started
77

8-
Welcome to the Netlify Skew Protection package documentation, a library to seamlessly add a [Skew Protection](https://www.industrialempathy.com/posts/version-skew/) feature to your [Netlify](https://www.netlify.com/) site. On this page, you'll discover how this package can help avoir version skew and learn how to set it up.
8+
Welcome to the Netlify Skew Protection package documentation, a library designed to seamlessly implement [Skew Protection](https://www.industrialempathy.com/posts/version-skew/) on your [Netlify](https://www.netlify.com/) site. This guide will show you how the package works to prevent version skew issues in your application and walk you through the steps to get it set up.
99

1010
## Problem
1111

12-
When deploying a new version of a static site, users who are still browsing the previous version may encounter `404` errors for static assets like JavaScript or CSS files. This happens because the new deployment instantly replaces the old one at the entry point, but users' files still references asset filenames that were unique to the previous build. As a result, when a user navigates to a page during this transition, the browser requests files may no longer exist, leading to broken pages and degraded user experience.
13-
14-
At Workleap, version skew most commonly occurs with [lazy-loaded routes](https://react.dev/reference/react/lazy).
12+
When deploying a new version of a static frontend application, users who are still browsing the previous version may encounter `404` errors for static assets like JavaScript or CSS files. This happens because the new deployment instantly replaces the old one, but users' files still reference asset filenames that were unique to the previous deployment. As a result, when a user navigates to a page during this transition, the browser requests files **may no longer exist**, leading to broken pages and degraded user experience. At Workleap, version skew most commonly occurs with [lazy-loaded routes](https://react.dev/reference/react/lazy).
1513

1614
## Solution
1715

18-
Skew Protection addresses this by maintaining a consistent experience for each user session. It does so by assigning a cookie when a user first fetch the entry point, tying that session to a specific deployment id. All subsequent asset requests are routed to that specific deploy URL (e.g., https://deploy-id--your-site.netlify.app), ensuring that users always receive the correct asset versions associated with the entry point they were served. This prevents asset mismatches and eliminates `404` errors caused by mid-session deploy transitions, resulting in smoother, safer releases.
16+
Skew Protection addresses this by maintaining a consistent experience for each user session. It does so by **assigning a cookie when** a user first fetch the entry point, **tying** that **session** to a specific **deployment id**. All subsequent asset requests are routed to that specific deploy URL (e.g., `https://deploy-id--your-site.netlify.app`), ensuring that users always receive the correct asset versions associated with the deployment they were served initially. This prevents asset mismatches and eliminates `404` errors caused by mid-session deploy transitions, resulting in smoother, safer releases.
1917

2018
## Set up Skew Protection
2119

22-
Let's [create an edge function](#create-the-edge-function), then [register the edge function](#register-the-edge-function), [build the edge function](#build-the-edge-function), and finally [configure the Netlify site](#configure-the-netlify-site).
20+
To enable Skew Protection on your Netlify site, you'll need to follow four key steps:
21+
22+
1. [Create the Edge Function](#create-the-edge-function)
23+
2. [Register the Edge Function](#register-the-edge-function)
24+
3. [Build the Edge Function](#build-the-edge-function)
25+
4. [Provide a secret](#provide-a-secret)
26+
27+
### Create the Edge Function
2328

24-
### Create the edge function
29+
Netlify's mechanism for intercepting and rerouting CDN requests is called [Edge Functions](https://docs.netlify.com/edge-functions/overview/). They act as middleware between incoming requests and your site's static files.
2530

26-
First, open a terminal at the root of the web application project that will include the Netlify [edge function](https://docs.netlify.com/edge-functions/overview/) and install the following packages:
31+
First, open a terminal at the root of the project where you'll define the Edge Function. Then install the following package:
2732

2833
+++ pnpm
2934
```bash
@@ -43,7 +48,7 @@ npm install -D @workleap/netlify-skew-protection
4348
While you can use any package manager to develop an application with Squide, it is highly recommended that you use PNPM as the guides has been developed and tested with PNPM.
4449
!!!
4550

46-
Then, create the edge function under a `netlify` folder and name the file `skew-protection.ts` (yes the file will be in TypeScript):
51+
Next, create a `netlify` folder at the root of the project and add a file named `skew-protection.ts`:
4752

4853
``` !#2-3
4954
web-project
@@ -52,25 +57,37 @@ web-project
5257
├── package.json
5358
```
5459

55-
Finally, open the `skew-protection.ts` file and paste the following content:
60+
Finally, open the `skew-protection.ts` file and paste in the contents for either [SPA mode](#spa-mode) or [entrypoints ](#entrypoints-mode), depending on the context of your application.
61+
62+
#### SPA mode
63+
64+
```ts skew-protection.ts
65+
import { config, createSkewProtectionFunction } from "@workleap/netlify-skew-protection";
66+
67+
const fct = createSkewProtectionFunction("spa");
68+
69+
export { config, fct as default };
70+
```
71+
72+
#### Entrypoints mode
5673

5774
```ts skew-protection.ts
5875
import { config, createSkewProtectionFunction } from "@workleap/netlify-skew-protection";
5976

60-
const fct = createSkewProtectionFunction(["/", "/index.html"]);
77+
const fct = createSkewProtectionFunction("entrypoints", {
78+
entrypoints: ["/"]
79+
});
6180

6281
export { config, fct as default };
6382
```
6483

6584
!!!info
66-
The previous code :point_up: assumes that the application entry point is a `index.html` file. If the application entry point is different, make sure to replace `/index.html` for the actual entry point of the application.
85+
The example above assumes that the application's entry point is `index.html`. If your app uses a different entry point, be sure to replace `/` with the correct path.
6786
!!!
6887

69-
### Register the edge function
70-
71-
Now, let's register the edge function with Netlify.
88+
### Register the Edge Function
7289

73-
If the application doesn't have a `netlify.toml` file yet, create a new one at the root of the project:
90+
Now, let’s register the Edge Function with Netlify. If the project doesn't already include a `netlify.toml` file, create one at the root of the project:
7491

7592
``` !#4
7693
web-project
@@ -80,7 +97,7 @@ web-project
8097
├── package.json
8198
```
8299

83-
Open the `netlify.toml` file and register the edge-function by pasting the following content:
100+
Then, open the `netlify.toml` file and add/replace the following configuration to register the Edge Function:
84101

85102
``` netlify.toml
86103
[build]
@@ -91,21 +108,15 @@ Open the `netlify.toml` file and register the edge-function by pasting the follo
91108
function = "skew-protection"
92109
```
93110

94-
### Build the edge function
95-
96-
Finally, depending of how the application is deployed to a Netlify site, additional steps might be required.
111+
### Build the Edge Function
97112

98-
#### From Netlify CLI
113+
If your application is deployed using a combination of an Azure DevOps pipeline or a GitHub Action along with the Netlify CLI, you're all set, no additional steps are required to build the Edge Function.
99114

100-
If the application is deployed to it's Netlify site using the [Netlify CLI](https://docs.netlify.com/cli/get-started/), your good to go, no additional steps are required.
115+
However, if your application is built and deployed using [Netlify Continuous Deployment](https://www.netlify.com/blog/enhance-your-development-workflow-with-continuous-deployment), an existing [limitation](https://developers.netlify.com/sdk/edge-functions/get-started#limitations) in Netlify’s Edge Function support for imported NPM packages requires additional steps. In this case, you'll need to explicitly build the Edge Function using [Rslib](https://lib.rsbuild.dev/).
101116

102-
#### From Netlify CD
117+
#### Rslib
103118

104-
If the application is deployed to it's Netlify site with the Netlify CD, you might hit a [limitation](https://developers.netlify.com/sdk/edge-functions/get-started#limitations) with the imports of an NPM package in a Netlify edge function. The solution is to either build the edge function manually using [Rslib](#rslib) or importing the NPM package through the intermediate of [esm.sh](#esmsh).
105-
106-
##### Rslib
107-
108-
First, open a terminal at the root of the web application project that will include the Netlify [edge function](https://docs.netlify.com/edge-functions/overview/) and install the following packages:
119+
First, open a terminal at the root of the project and install the following dependency:
109120

110121
+++ pnpm
111122
```bash
@@ -125,7 +136,7 @@ npm install -D @rslib/core
125136
While you can use any package manager to develop an application with Squide, it is highly recommended that you use PNPM as the guides has been developed and tested with PNPM.
126137
!!!
127138

128-
Then, create a `rslib.edge-functions.ts` file at the root of the project:
139+
Then, create a file named `rslib.edge-functions.ts` at the root of the project:
129140

130141
``` !#5
131142
web-project
@@ -136,7 +147,7 @@ web-project
136147
├── package.json
137148
```
138149

139-
Open the `rslib.edge-functions.ts` file and paste the following content:
150+
Then, open the `rslib.edge-functions.ts` file and paste the following content:
140151

141152
```ts rslib.edge-functions.ts
142153
import { defineConfig } from "@rslib/core";
@@ -163,7 +174,11 @@ export default defineConfig({
163174
});
164175
```
165176

166-
Next, open the `netlify.toml` created earlier and update the `build.edge_functions` property to match the `dist` path of the rslib configuration file:
177+
!!!warning
178+
If the build of the application is output in the same `dist` path as the edge function, make sure to output the application files in a subfolder like `dist/app` rather than the root of the `dist` folder.
179+
!!!
180+
181+
Then, update the `netlify.toml` to point to the new Edge Function build output:
167182

168183
```!#2 netlify.toml
169184
[build]
@@ -174,7 +189,7 @@ Next, open the `netlify.toml` created earlier and update the `build.edge_functio
174189
function = "skew-protection"
175190
```
176191

177-
Finally, update the build script of the project to build the edge functions as well:
192+
Finally, update the project's `package.json` file to build both, the application and the Edge Function:
178193

179194
```json !#4 package.json
180195
"scripts": {
@@ -184,48 +199,62 @@ Finally, update the build script of the project to build the edge functions as w
184199
}
185200
```
186201

187-
##### esm.sh
202+
#### The esm.sh alternative
188203

189-
Importing the NPM package with [esm.sh](https://esm.sh/) is more straightforward but involves an additional third party. To import the [@workleap/netlify-skew-protection](https://www.npmjs.com/package/@workleap/netlify-skew-protection) package using `esm.sh`, import the package of the package for the following code:
204+
Using [esm.sh](https://esm.sh/) to import the package is a more straightforward approach, but it introduces an additional third-party dependency. To load the [@workleap/netlify-skew-protection](https://www.npmjs.com/package/@workleap/netlify-skew-protection) package via `esm.sh`, you can use the following import directly in your Edge Function:
190205

191206
```ts skew-protection.ts
192207
import { config, createSkewProtectionFunction } from "https://esm.sh/@workleap/netlify-skew-protection";
193208
```
194209

195-
Since the package is downloaded from a third party server rather than being imported from a `node_modules` folder, the `@workleap/netlify-skew-protection` dependency can be removed from the project `package.json`.
210+
Since the package is fetched from a third-party CDN instead of being installed locally via `node_modules`, you can safely remove `@workleap/netlify-skew-protection` from the `package.json` file.
196211

197212
!!!info
198-
The previous example :point_up: always import the latest version of the package. [esm.sh](https://esm.sh/) also support specifying a specific version of the package if needed.
213+
The example above always pulls the **latest version** of the package. For more predictable behavior, [esm.sh](https://esm.sh/) also supports importing a **specific version**, which is a safer and recommended option for production use.
199214
!!!
200215

201-
### Configure the Netlify site
216+
### Provide a secret
217+
218+
To secure the [HMAC](https://en.wikipedia.org/wiki/HMAC) signature used by the Skew Protection mechanism, you'll need to generate a new secret. Use the [OpenSSL CLI](https://docs.openssl.org/3.4/man1/openssl/) to create a strong, random value.
202219

203-
Now, generate a new secret using the [OpenSSL CLI](https://docs.openssl.org/3.4/man1/openssl/):
220+
Open a Bash terminal (or any terminal compatible with OpenSSL) and run the following command:
204221

205222
```bash
206223
openssl rand -base64 32
207224
```
208225

209-
Save the generated value and to go the application [Netlify site](https://app.netlify.com/). Add a new environment variabled named `SKEW_PROTECTION_SECRET` and set the generated secret as the value.
226+
Copy the generated value, then navigate to your project's [Netlify site](https://app.netlify.com/) settings. Add a new environment variable named `SKEW_PROTECTION_SECRET` with the generated secret as its value:
227+
228+
| Variable | Value |
229+
| --- | --- |
230+
| `SKEW_PROTECTION_SECRET` | The generated secret. |
210231

211232
## Try it :rocket:
212233

213-
To test your new set up, follow these steps:
234+
To verify that Skew Protection is working as expected, follow these steps:
235+
236+
1. Open a browser with the [Dev Tools](https://developer.chrome.com/docs/devtools) open, and go to the Network tab.
237+
238+
2. Locate the request for the application's entry point file and inspect the response headers.
214239

215-
1. Open a browser with the [Dev Tools](https://developer.chrome.com/docs/devtools) opened to the network tab and navigate to your application.
240+
3. You should see a `nf_sp` cookie (or the custom name you configured for the Skew Protection cookie) in the response:
216241

217-
2. Search for the entry point file of the application and take a look at the response headers.
242+
:::align-image-left
243+
![](./static/entrypoint_cookie.png)
244+
:::
218245

219-
3. The response should include a `nf_sp` cookie (or wathever name you choose for the Skew Protection cookie)
246+
4. Refresh the page, and inspect the request headers of a JS and CSS assets. The request should include the same `nf_sp cookie`, confirming that the session is pinned to the original deploy:
220247

221-
4. Then, navigate to a lazy loaded route and refresh the page and find an asset request. The asset request should include a `nf_sp` cookie.
248+
:::align-image-left
249+
![](./static/asset_cookie.png)
250+
:::
222251

223252
### Troubleshoot issues
224253

225-
- If the cookie is not set, troubleshoot the issue using Netlify [edge functions logs](https://docs.netlify.com/edge-functions/get-started/#monitor).
254+
- If the Skew Protection cookie is not being set, use the [Edge Functions logs](https://docs.netlify.com/edge-functions/get-started/#monitor) in Netlify to investigate the issue.
226255

227-
- If the logs mentions that the edge function is not installed properly, this is probably because the site doesn't include an `SKEW_PROTECTION_SECRET` environment variable.
256+
- If the logs indicate that the Edge Function isn't installed correctly, it's likely because the `SKEW_PROTECTION_SECRET` environment variable is missing from the Netlify site's configuration.
228257

229-
- If the requests to previous asset files are not re-routed, set the [debug](./available-options.md#debug) option, deploy the edge function again and troubleshoot the issue using the [edge functions logs](https://docs.netlify.com/edge-functions/get-started/#monitor).
258+
- If requests to previous deploy assets aren't being re-routed as expected, enable the [debug](./available-options.md#debug) option, redeploy the Edge Function, and inspect the [Edge Functions logs](https://docs.netlify.com/edge-functions/get-started/#monitor) for details.
230259

231260

docs/static/asset_cookie.png

16.5 KB
Loading

docs/static/entrypoint_cookie.png

33.9 KB
Loading

0 commit comments

Comments
 (0)