diff --git a/astro.config.js b/astro.config.js
index 3b180e7..1264523 100644
--- a/astro.config.js
+++ b/astro.config.js
@@ -28,6 +28,9 @@ export default defineConfig({
'/developer/integrations/addresses': '/developer/integrations/reference',
'/developer/smart-contract/hyperstaking_tech': '/learn/hyperstaking',
'/learn/deep-dive/dusk-evm': '/learn/dusk-evm',
+ // Cloudflare owns the production HTTP 301 for both legacy URL variants.
+ // Keep this Astro redirect as a noindex/canonical static-build fallback.
+ '/learn/transactions': '/learn/deep-dive/duskds-tx-models/',
'/developer/smart-contracts-dusk-evm/deploy-on-evm': '/developer/duskevm/quickstart',
'/developer/smart-contracts-duskds': '/developer/duskvm/overview',
'/developer/duskds': '/developer/duskvm/overview',
diff --git a/test/machine-files.test.mjs b/test/machine-files.test.mjs
index 2b49c43..b22b4d5 100644
--- a/test/machine-files.test.mjs
+++ b/test/machine-files.test.mjs
@@ -39,3 +39,20 @@ test("documentation pages declare a complete default social preview image", asyn
assert.match(config, /dusk-social-preview-og\.png/);
assert.match(config, /dusk-social-preview-twitter\.png/);
});
+
+test("the static build provides a canonical noindex fallback for the legacy transaction guide", async () => {
+ const redirectPage = await readFile(
+ new URL("../dist/learn/transactions/index.html", import.meta.url),
+ "utf8",
+ );
+
+ assert.match(
+ redirectPage,
+ //,
+ );
+ assert.match(redirectPage, //);
+ assert.match(
+ redirectPage,
+ //,
+ );
+});