This commit is contained in:
Rushmore75 2025-04-17 12:27:52 -06:00
parent 31c476a48d
commit ff469e2bf6
9 changed files with 946 additions and 848 deletions

View File

@ -1,9 +1,19 @@
// @ts-check // @ts-check
import { defineConfig } from 'astro/config'; import { defineConfig } from 'astro/config';
import node from '@astrojs/node';
// https://astro.build/config // https://astro.build/config
export default defineConfig({ export default defineConfig({
site: "https://demo.site", site: "https://demo.site",
// reidrects abc.xyz/ -> abc.xyz
trailingSlash: 'never' // reidrects abc.xyz/ -> abc.xyz
}); trailingSlash: 'never',
// cookie stuff can't be prerendered
output: 'server',
adapter: node({
mode: 'standalone'
})
});

1665
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -9,6 +9,7 @@
"astro": "astro" "astro": "astro"
}, },
"dependencies": { "dependencies": {
"@astrojs/node": "^9.2.0",
"astro": "^5.2.5" "astro": "^5.2.5"
} }
} }

4
src/core.ts Normal file
View File

@ -0,0 +1,4 @@
export enum Split {
A = "A",
B = "B",
}

5
src/env.d.ts vendored Normal file
View File

@ -0,0 +1,5 @@
declare namespace App {
interface Locals {
split: Split
}
}

24
src/middleware.ts Normal file
View File

@ -0,0 +1,24 @@
import { defineMiddleware } from "astro:middleware";
import { Split } from "./core";
// Get/Set split cookie and put it on the Astro object
export const onRequest = defineMiddleware(async (context, next) => {
let split: Split;
// see if we are already running a split
let cookie = context.cookies.get("split")
if (!cookie) { // no split detected
let i = Math.floor(Math.random() * Object.keys(Split).length);
split = Object.values(Split)[i] as Split;
context.cookies.set("split", Split[split])
} else { // split detected!
let v = cookie.value;
split = v as unknown as Split;
}
context.locals.split = split
return next()
})

45
src/pages/checkout.astro Normal file
View File

@ -0,0 +1,45 @@
---
import Base from "../partials/base.astro";
let email_error = false;
let addr_error = false;
// form submission
if (Astro.request.method === "POST") {
try {
const data = await Astro.request.formData()
const email = data.get("email")
const addr = data.get("address")
/*
some logic to process the order
...
*/
if (email == "") {
email_error = true
}
if (addr == "") {
addr_error = true
}
if (!email_error && !addr_error) {
console.log("Order from:", email, "who was in funnel:", Astro.locals.split);
return Astro.redirect("/thank_you")
}
} catch (error) {
console.log(error)
}
}
---
<Base title="Checkout" desc="$$$">
<h1>Checkout</h1>
<form method="post">
<input name="email" placeholder="Email" type="email">
<input name="address" placeholder="Mailing Address" type="text">
<button type="submit">Submit</button>
</form>
</Base>

View File

@ -1,10 +1,26 @@
--- ---
import { Split } from "../core";
import Head from "../partials/base.astro" import Head from "../partials/base.astro"
// Welcome to Astro! Wondering what to do next? Check out the Astro documentation at https://docs.astro.build let hero;
// Don't want to use any of this? Delete everything in this file, the `assets`, `components`, and `layouts` directories, and start fresh.
switch (Astro.locals.split) {
case Split.A:
hero = "Hello"
break;
case Split.B:
hero = "Welcome"
break;
default:
hero = "Hello"
console.error("Non-exhaustive switch statement used!")
break;
}
--- ---
<Head title='Home' desc='Where the party is happeneing!'> <Head title='Home' desc='Doing A/B testing'>
<h1>{hero}</h1>
<p>Hello world!</p> <p>Hello world!</p>
<a href="/checkout">Checkout</a>
</Head> </Head>

View File

@ -0,0 +1,8 @@
---
import Base from "../partials/base.astro";
---
<Base title="Thank You!" desc="The landing page after a purchase">
<h1>Thank you!</h1>
<a href="/">Go home</a>
</Base>