diff --git a/src/content/docs/rules/snippets/examples/custom-cache.mdx b/src/content/docs/rules/snippets/examples/custom-cache.mdx
new file mode 100644
index 00000000000000..a38df5964988bf
--- /dev/null
+++ b/src/content/docs/rules/snippets/examples/custom-cache.mdx
@@ -0,0 +1,100 @@
+---
+type: example
+summary: Control cache programmatically. Use this template to optimize performance and implement custom caching strategies.
+goal:
+ - Other
+operation:
+ - Cache
+products:
+ - Snippets
+pcx_content_type: example
+title: Custom cache
+description: Store, retrieve, and remove assets from cache programmatically. Use this template to optimize performance and implement custom caching strategies.
+---
+
+```js
+// Define configurable cache duration in seconds (default: 30 days)
+const CACHE_DURATION_SECONDS = 30 * 24 * 60 * 60;
+
+// Define which parts of the request to include in the cache key
+const USE_PATH = true; // Include path in the cache key
+const USE_QUERY_STRING = true; // Include query string in the cache key
+const INCLUDE_HEADERS = ["User-Agent"]; // Headers to include in the cache key
+
+export default {
+ async fetch(request, env, ctx) {
+ // Generate a custom cache key based on user preferences
+ const cacheKey = createCacheKey(request);
+ console.log(`Retrieving cache for: ${cacheKey.url}.`)
+
+ // Access the default Cache API
+ const cache = caches.default;
+
+ // Attempt to retrieve the cached response
+ let response = await cache.match(cacheKey);
+
+ if (!response) {
+ // Cache miss: Fetch the asset from the origin
+ console.log(`Cache miss for: ${cacheKey.url}. Fetching from origin...`);
+ response = await fetch(request);
+
+ // Wrap the origin response for caching
+ response = new Response(response.body, response);
+
+ // Set Cache-Control headers to define the TTL
+ response.headers.set("Cache-Control", `s-maxage=${CACHE_DURATION_SECONDS}`);
+ response.headers.set("x-snippets-cache", "stored");
+
+ // Store the response in the cache
+ await cache.put(cacheKey, response.clone());
+ } else {
+ // Cache hit: Return the cached response
+ console.log(`Cache hit for: ${cacheKey.url}.`);
+ response = new Response(response.body, response);
+ response.headers.set("x-snippets-cache", "hit");
+
+ // Optionally check if the cache should expire based on age
+ const ageHeader = response.headers.get("Age");
+ if (ageHeader && parseInt(ageHeader, 10) > CACHE_DURATION_SECONDS) {
+ console.log(`Cache expired for: ${cacheKey.url}. Deleting cached response...`);
+ await cache.delete(cacheKey);
+ response.headers.set("x-snippets-cache", "deleted");
+ }
+ }
+
+ // Return the response to the client
+ return response;
+ },
+};
+
+/**
+ * Function to create a custom cache key based on request properties
+ * @param {Request} request - The incoming request object
+ * @returns {Request} - A valid cache key based on the URL
+ */
+function createCacheKey(request) {
+ const url = new URL(request.url); // Use the request's base URL
+ const cacheKey = new URL(url.origin); // Start with the origin (scheme + hostname)
+
+ // Optionally include the path
+ if (USE_PATH) {
+ cacheKey.pathname = url.pathname;
+ }
+
+ // Optionally include the query string
+ if (USE_QUERY_STRING) {
+ cacheKey.search = url.search;
+ }
+
+ // Optionally include specific headers
+ if (INCLUDE_HEADERS.length > 0) {
+ const headerParts = INCLUDE_HEADERS.map(header => `${header}=${request.headers.get(header) || ""}`).join("&");
+ cacheKey.searchParams.append("headers", headerParts);
+ }
+
+ // Return the constructed URL as the cache key
+ return new Request(cacheKey.toString(), {
+ method: "GET"
+ });
+}
+```
diff --git a/src/content/docs/rules/snippets/examples/hex-timestamp.mdx b/src/content/docs/rules/snippets/examples/hex-timestamp.mdx
new file mode 100644
index 00000000000000..f985c281d081bc
--- /dev/null
+++ b/src/content/docs/rules/snippets/examples/hex-timestamp.mdx
@@ -0,0 +1,39 @@
+---
+type: example
+summary: Add a custom header to requests sent to the origin server with the current timestamp in hexadecimal format.
+goal:
+ - Manage headers
+operation:
+ - Request modification
+products:
+ - Snippets
+pcx_content_type: example
+title: Add HEX timestamp to a request header
+description: Add a custom header to requests sent to the origin server with the current timestamp in hexadecimal format for debugging, tracking, or custom routing purposes.
+---
+
+```js
+export default {
+ async fetch(request) {
+ // Get the current timestamp
+ const timestamp = Date.now();
+
+ // Convert the timestamp to hexadecimal format
+ const hexTimestamp = timestamp.toString(16);
+
+ // Clone the request and add the custom header
+ const modifiedRequest = new Request(request, {
+ headers: new Headers(request.headers)
+ });
+ modifiedRequest.headers.set("X-Hex-Timestamp", hexTimestamp);
+
+ // Log the custom header for debugging
+ console.log(`X-Hex-Timestamp: ${hexTimestamp}`);
+
+ // Pass the modified request to the origin
+ const response = await fetch(modifiedRequest);
+
+ return response;
+ },
+};
+```
\ No newline at end of file
diff --git a/src/content/docs/rules/snippets/examples/maintenance.mdx b/src/content/docs/rules/snippets/examples/maintenance.mdx
new file mode 100644
index 00000000000000..eacba1ec4e915f
--- /dev/null
+++ b/src/content/docs/rules/snippets/examples/maintenance.mdx
@@ -0,0 +1,102 @@
+---
+type: example
+summary: Serve a custom maintenance page. Ideal for downtime notifications, planned maintenance, or emergency messages.
+goal:
+ - Routing
+operation:
+ - Redirect
+products:
+ - Snippets
+pcx_content_type: example
+title: Maintenance page
+description: Serve a custom maintenance page instead of fetching content from the origin server or cache. Ideal for downtime notifications, planned maintenance, or emergency messages.
+---
+
+```js
+// Define your customizable inputs
+const title = "We'll Be Right Back!";
+const message = "Our site is currently undergoing scheduled maintenance. We’re working hard to bring you a better experience. Thank you for your patience and understanding.";
+const estimatedTime = "1 hour";
+const contactEmail = "support@example.com";
+const contactPhone = "+1 234 567 89";
+
+export default {
+ async fetch(request) {
+ // Serve the maintenance page as a response
+ return new Response(generateMaintenancePage(), {
+ headers: { "Content-Type": "text/html" },
+ });
+ },
+};
+
+function generateMaintenancePage() {
+ return `
+
+
+
+
+
+ ${title}
+
+
+
+
+
${title}
+
${message}
+
If all goes to plan, we'll be back online in ${estimatedTime}. 🚀
+
+ Need help? Reach out to us at ${contactEmail}
+ or call us at ${contactPhone}.
+
+
+
+
+ `;
+}
+```
diff --git a/src/content/docs/rules/snippets/examples/redirect-forbidden-status.mdx b/src/content/docs/rules/snippets/examples/redirect-forbidden-status.mdx
index 21fe7d33bd08b1..d4b8c1808aa2f4 100644
--- a/src/content/docs/rules/snippets/examples/redirect-forbidden-status.mdx
+++ b/src/content/docs/rules/snippets/examples/redirect-forbidden-status.mdx
@@ -9,7 +9,7 @@ operation:
products:
- Snippets
pcx_content_type: example
-title: Redirect `403 Forbidden` to a different page
+title: Redirect 403 Forbidden to a different page
description: If origin responded with `403 Forbidden` error code, redirect to
different page.
---
diff --git a/src/content/docs/rules/snippets/examples/rewrite-site-links.mdx b/src/content/docs/rules/snippets/examples/rewrite-site-links.mdx
new file mode 100644
index 00000000000000..78a7063352ccc0
--- /dev/null
+++ b/src/content/docs/rules/snippets/examples/rewrite-site-links.mdx
@@ -0,0 +1,54 @@
+---
+type: example
+summary: Dynamically rewrite links in HTML responses.
+goal:
+ - Other
+operation:
+ - Response modification
+products:
+ - Snippets
+pcx_content_type: example
+title: Rewrite links on HTML pages
+description: Dynamically rewrite links in HTML responses. This is useful for site migrations and branding updates.
+---
+
+```js
+export default {
+ async fetch(request) {
+ // Define the old hostname here.
+ const OLD_URL = "oldsite.com";
+ // Then add your new hostname that should replace the old one.
+ const NEW_URL = "newsite.com";
+
+ class AttributeRewriter {
+ constructor(attributeName) {
+ this.attributeName = attributeName;
+ }
+ element(element) {
+ const attribute = element.getAttribute(this.attributeName);
+ if (attribute) {
+ element.setAttribute(
+ this.attributeName,
+ attribute.replace(OLD_URL, NEW_URL),
+ );
+ }
+ }
+ }
+
+ const rewriter = new HTMLRewriter()
+ .on("a", new AttributeRewriter("href"))
+ .on("img", new AttributeRewriter("src"));
+
+ const res = await fetch(request);
+ const contentType = res.headers.get("Content-Type");
+
+ // If the response is HTML, it can be transformed with
+ // HTMLRewriter -- otherwise, it should pass through
+ if (contentType.startsWith("text/html")) {
+ return rewriter.transform(res);
+ } else {
+ return res;
+ }
+ },
+};
+```
\ No newline at end of file
diff --git a/src/content/docs/rules/transform/examples/rewrite-moved-section.mdx b/src/content/docs/rules/transform/examples/rewrite-moved-section.mdx
index e936abc947db0d..41d6c1672a94a6 100644
--- a/src/content/docs/rules/transform/examples/rewrite-moved-section.mdx
+++ b/src/content/docs/rules/transform/examples/rewrite-moved-section.mdx
@@ -13,22 +13,19 @@ description: Create a rewrite URL rule (part of Transform Rules) to rewrite
import { Example } from "~/components";
-To rewrite everything under `/blog/` to `/marketing/` you must modify the first component of the path (`/blog/`). Create a rewrite URL rule and use the [`regex_replace()`](/ruleset-engine/rules-language/functions/#regex_replace) function for this purpose:
+To rewrite everything under `/blog/` to `/marketing/`, create a new rewrite URL rule and define a dynamic URL path rewrite using [wildcard pattern parameters](/rules/transform/url-rewrite/create-dashboard/#wildcard-pattern-parameters):
-Text in **Expression Editor**:
+**When incoming requests match**
-```txt
-starts_with(http.request.uri.path, "/blog/")
-```
+- **Wildcard pattern**
+ - **Request URL**: `https:///blog/*`
-Text after **Path** > **Rewrite to...** > _Dynamic_:
-
-```txt
-regex_replace(http.request.uri.path, "^/blog/", "/marketing/")
-```
+**Then rewrite the path and/or query**
+- **Target path**: `/blog/*`
+- **Rewrite to**: `/marketing/${1}`
-The `regex_replace()` function matches the path component on a regular expression (`^/blog/`) and then provides a replacement for that match (`/marketing/`).
+Make sure to replace `` with your actual hostname and adjust the example paths according to your setup.
\ No newline at end of file
diff --git a/src/content/docs/rules/transform/examples/rewrite-path-archived-posts.mdx b/src/content/docs/rules/transform/examples/rewrite-path-archived-posts.mdx
index 918f319f9b6f01..3111e09025af89 100644
--- a/src/content/docs/rules/transform/examples/rewrite-path-archived-posts.mdx
+++ b/src/content/docs/rules/transform/examples/rewrite-path-archived-posts.mdx
@@ -13,22 +13,19 @@ description: Create a rewrite URL rule (part of Transform Rules) to rewrite any
import { Example } from "~/components";
-To rewrite all requests to `/news/2012/...` to `/archive/news/2012/...` you must add a reference to the content of the original URL. Create a new rewrite URL rule and define a dynamic URL path rewrite using an expression:
+To rewrite all requests to `/news/2012/...` to `/archive/news/2012/...` you must add a reference to the content of the original URL. Create a new rewrite URL rule and define a dynamic URL path rewrite using [wildcard pattern parameters](/rules/transform/url-rewrite/create-dashboard/#wildcard-pattern-parameters):
-Text in **Expression Editor**:
+**When incoming requests match**
-```txt
-starts_with(http.request.uri.path, "/news/2012/")
-```
+- **Wildcard pattern**
+ - **Request URL**: `https:///news/2012/*`
-Text after **Path** > **Rewrite to...** > _Dynamic_:
-
-```txt
-concat("/archive", http.request.uri.path)
-```
+**Then rewrite the path and/or query**
+- **Target path**: `/news/2012/*`
+- **Rewrite to**: `/archive/news/2012/${1}`
-The filter uses the [`starts_with()`](/ruleset-engine/rules-language/functions/#starts_with) function all paths starting with `/news/2012/`. The dynamic path rewrite uses the [`concat()`](/ruleset-engine/rules-language/functions/#concat) function to concatenate a prefix to the original URL path of the HTTP request.
+Make sure to replace `` with your actual hostname and adjust the example paths according to your setup.
\ No newline at end of file
diff --git a/src/content/docs/rules/transform/examples/rewrite-path-object-storage.mdx b/src/content/docs/rules/transform/examples/rewrite-path-object-storage.mdx
new file mode 100644
index 00000000000000..babe5d640833a2
--- /dev/null
+++ b/src/content/docs/rules/transform/examples/rewrite-path-object-storage.mdx
@@ -0,0 +1,32 @@
+---
+pcx_content_type: example
+summary: Create a rewrite URL rule (part of Transform Rules) to remove
+ `/files/` from URI paths before routing request to your object storage bucket.
+products:
+ - Transform Rules
+operation:
+ - Rewrite URL
+title: Rewrite path for object storage bucket
+description: Create a rewrite URL rule (part of Transform Rules) to rewrite any
+ requests for `/files/...` URI paths to `/...`.
+---
+
+import { Example } from "~/components";
+
+To remove `/files/` from URI paths before routing request to your object storage bucket, create a new rewrite URL rule and define a dynamic URL path rewrite using [wildcard pattern parameters](/rules/transform/url-rewrite/create-dashboard/#wildcard-pattern-parameters):
+
+
+
+**When incoming requests match**
+
+- **Wildcard pattern**
+ - **Request URL**: `https:///files/*`
+
+**Then rewrite the path and/or query**
+- **Target path**: `/files/*`
+- **Rewrite to**: `/${1}`
+
+
+
+Make sure to replace `` with your actual hostname and adjust the example paths according to your setup.
+Then, use [Cloud Connector](/rules/cloud-connector/) to route traffic to an object storage bucket.
\ No newline at end of file