Halloween sweaters, tees, hats, mugs, and home decor. Shop Spooky Threads for cozy, spooky-cute apparel and gifts all season long.
CommerceTypeScript · CSSGitHub @SuzanneV0OnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
No updates detected yet. GitHub releases will appear here.
Owners of public repositories under a personal GitHub account can sign in to verify ownership and manage the introduction themselves. No administrator approval is needed.
Sign in, generate a verification file, and commit it to this repository’s default branch within 30 minutes. Files on other branches or forks do not count. Then check the file below to manage the project without administrator approval. Keep the file to retain your access.
If needed, you will go to sign-in. After signing in, return here and press your chosen verification button again.
Run /nomorevibe verify in your project folder to verify ownership and manage the introduction yourself.
Verify in one minuteAsk about other verification options
Halloween apparel shop — practice project for a course on AI chatbot + Stripe integration
Translation pending
Taken from the repository README
Loading the full README. The saved excerpt is shown below.
A Halloween-themed apparel and home goods shop, built as a practice project for a course on integrating AI chatbots and Stripe payments into an online store. This is a dry run before the real store launches.
• Next.js (App Router, TypeScript)
• Supabase — database, auth, and admin backend
• Stripe Checkout for payments
• Anthropic API (@anthropic-ai/sdk, Claude Haiku 4.5) for the shopping assistant chatbot
• Resend for transactional email (welcome, order confirmation, password reset)Read the full README ↗A Halloween-themed apparel and home goods shop, built as a practice project for a course on integrating AI chatbots and Stripe payments into an online store. This is a dry run before the real store launches.
@anthropic-ai/sdk, Claude Haiku 4.5) for the shopping assistant chatbotnpm install
npm run db:migrate # create the tables in your Turso database
npm run db:seed # load the product catalog from db/catalog.json
npm run dev
.env.local needs these to run at all:
TURSO_DATABASE_URL / TURSO_AUTH_TOKEN — from the Turso dashboard: open the database, copy its URL (libsql://…) and click Create Token. The token is server-only; the browser never talks to the database directly, only through the app's API routes.NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY / CLERK_SECRET_KEY — from the Clerk dashboard → API keys (clerk init writes these for you).Add your own ANTHROPIC_API_KEY (create one at console.anthropic.com — new accounts get a small free credit) to turn on the chat assistant.
Checkout needs three more values in .env.local:
STRIPE_SECRET_KEY / STRIPE_PUBLISHABLE_KEY — from the Stripe dashboard (test mode)STRIPE_WEBHOOK_SECRET — run stripe listen --forward-to localhost:3000/api/webhooks/stripe locally to get one, or add a webhook endpoint in the Stripe dashboard pointing at <your-deployed-url>/api/webhooks/stripe (subscribed to checkout.session.completed) and use the signing secret it gives youTransactional email needs one more value:
RESEND_API_KEY — from the Resend dashboard. Sending also requires verifying a domain in Resend (Domains → Add Domain) and adding the SPF/DKIM records it gives you at your DNS provider — until that's done, lib/email/send.ts logs a warning and skips sending instead of failing the request. Emails are currently sent from [email protected] (EMAIL_FROM in lib/site.ts).The contact form's spam protection needs two more values:
NEXT_PUBLIC_RECAPTCHA_SITE_KEY / RECAPTCHA_SECRET_KEY — register the site (v2 "I'm not a robot" checkbox) at the reCAPTCHA admin console. Without these, /contact skips rendering the widget and the API route skips verification — fine for local dev, but set them in production.Error monitoring needs four more values, all provisioned automatically in Vercel by the Sentry integration (Vercel dashboard → Project → Integrations → Sentry → Connect to Project) — pull them into .env.local with vc env pull if you want errors reported locally too:
NEXT_PUBLIC_SENTRY_DSN — where the SDK sends events. Safe to expose client-side; it's a write-only ingestion address, not a secret.SENTRY_ORG / SENTRY_PROJECT / SENTRY_AUTH_TOKEN — used at build time to upload source maps so stack traces in Sentry show real code instead of minified output.public/products/, components/ProductPhoto.tsx) — falling back to hand-illustrated SVG art in the brand color palette (components/ProductArt.tsx, lib/productArt.ts) if a photo fails to load.components/CartProvider.tsx). Checkout requires being logged in, creates a Stripe Checkout Session (app/api/checkout/route.ts) with prices looked up server-side (never trusts the client), and a webhook (app/api/webhooks/stripe/route.ts) creates the orders/order_items rows once payment completes./sign-in, /sign-up; the old /login and /signup URLs redirect there), with an account area for saved items, wishlist, addresses, and order history (app/account/*)./admin (gated to accounts with is_admin = true on their profile) for managing products and order statuses./whimsical-goth is a pillar page targeting "whimsical goth year round", linking out to four hand-written seasonal pages (/whimsical-goth/spring|summer|fall|winter) that each pull a real product row from a matching collection. All five are in app/sitemap.ts and linked from the footer.components/ChatWidget.tsx) backed by the Anthropic API (app/api/chat/route.ts), grounded in the live product catalog so it only recommends real products and links to them. Rate-limited to 5 messages/day per visitor./quiz matches shoppers to one of five tropes, saves the result to their profile if logged in, and recommends products from the matching collection. Rate-limited to 2 completions/day per visitor — unlimited for subscribers.Sign up for an account on the site, then find your user id (user_…) in the Clerk dashboard → Users, and run this in the Turso dashboard's SQL console (or ask Claude):
UPDATE profiles SET is_admin = 1 WHERE id = 'user_...';
app/ — pages (App Router)components/ — shared UI, providers (auth, cart), product artdb/schema.sql — the database tables; db/catalog.json — the product catalog (npm run db:seed)lib/db/client.ts — the server-only Turso client; lib/queries.ts — catalog queries; lib/auth.ts — Clerk session + profile helpersapp/api/ — every database write from the browser goes through a route here, scoped to the signed-in userlib/nav.ts — the site's nav/footer link structurelib/productArt.ts — per-product illustration color + motif mappingapp/api/chat/route.ts)app/api/checkout/route.ts) and move the cart to real checkoutorders rowsRESEND_API_KEY above/contact) — needs NEXT_PUBLIC_RECAPTCHA_SITE_KEY / RECAPTCHA_SECRET_KEY in production, see above/subscriptionsmode: "subscription"app/api/subscribe/route.tscheckout.session.completedprofiles.subscription_tierprevious_subscription_idapp/api/subscribe/cancel/route.tslib/rateLimit.ts and a single atomic upsert on the feature_usage table enforce the AI-feature daily limits server-side, keyed by account (logged in) or an anonymous cookie (guests) — so it can't be bypassed by clearing client state.lib/email/layout.ts) in the site's own color palette. Two emails: a welcome email the first time a new account is seen (getOrCreateProfile in lib/auth.ts), and an order confirmation sent from the Stripe webhook once an order is created. Password resets are handled by Clerk. Sending is best-effort: if RESEND_API_KEY isn't set or a domain isn't verified yet, it logs and moves on rather than blocking signup or checkout./contact (components/ContactForm.tsx), linked only from the footer. Name, email, a topic dropdown (general inquiry, orders, subscriptions, other), and a message — gated by a reCAPTCHA v2 checkbox verified server-side (app/api/contact/route.ts) before the message is emailed to CONTACT_EMAIL (lib/site.ts) via the same Resend layout used elsewhere.instrumentation.ts + instrumentation-client.ts capture unhandled errors from server, edge (middleware.ts), and client code; app/error.tsx and app/global-error.tsx catch React rendering errors and report them via Sentry.captureException while showing a branded fallback instead of a blank crash screen. next.config.ts uploads source maps at build time so stack traces show real code.