Go Live in 30 Minutes

Connect your real credentials to switch from demo mode to a fully operational SaaS.

1
Supabase
Auth · Database
2
Stripe
Payments · Webhooks
3
Resend
Transactional Email
You're in Interactive Demo Mode

The site is fully functional for testing: auth modals open, reports gate correctly, and Stripe buttons fire — but no data is persisted and no real payments are processed. Complete the steps below to go live.


Step 1 · Supabase — Auth & Database

Time: ~10 minutes · Cost: Free tier

Supabase handles user accounts, email verification, and your subscriber list.

1.1 Create a project

  1. Go to supabase.com and click New Project
  2. Choose a region close to your users (EU West for Spain-based)
  3. Save the database password somewhere secure

1.2 Get your API keys

From your project dashboard → Settings → API:

KeyWhere it goes
Project URLhugo.tomlsupabaseUrl
anon / public keyhugo.tomlsupabaseAnonKey
service_role key ⚠️GitHub Actions secret only — never in frontend

1.3 Run the database migration

Open Supabase → SQL Editor and paste this to create the profiles table:

-- Sync auth users to a public profiles table
create table if not exists public.profiles (
  id uuid references auth.users(id) on delete cascade primary key,
  email text unique not null,
  plan text not null default 'free',
  created_at timestamptz default now()
);

alter table public.profiles enable row level security;
create policy "Users can read own profile" on public.profiles
  for select using (auth.uid() = id);

-- Auto-create profile on signup
create or replace function public.handle_new_user()
returns trigger language plpgsql security definer as $$
begin
  insert into public.profiles (id, email)
  values (new.id, new.email)
  on conflict (id) do nothing;
  return new;
end;
$$;

create trigger on_auth_user_created
  after insert on auth.users
  for each row execute procedure public.handle_new_user();

1.4 Update hugo.toml

[params]
  supabaseUrl      = "https://YOUR_PROJECT_ID.supabase.co"
  supabaseAnonKey  = "YOUR_ANON_KEY_HERE"

After this, rebuild and redeploy — the amber demo banner will disappear automatically.


Step 2 · Stripe — Payments

Time: ~15 minutes · Cost: 2.9% + 30¢ per transaction

2.1 Create products in Stripe dashboard

Go to dashboard.stripe.com/products and create:

ProductPriceBilling
Early Access$9.99Monthly recurring
Professional$29.99Monthly recurring

Copy the Price ID (looks like price_1ABC...) for each plan.

2.2 Create a Supabase Edge Function for checkout

In your terminal (from the project root):

supabase functions new create-checkout

Paste this into supabase/functions/create-checkout/index.ts:

import Stripe from 'https://esm.sh/stripe@14?target=deno'
import { createClient } from 'https://esm.sh/@supabase/supabase-js@2'

const stripe = new Stripe(Deno.env.get('STRIPE_SECRET_KEY')!, { apiVersion: '2024-06-20' })

Deno.serve(async (req) => {
  const { priceId } = await req.json()
  const authHeader = req.headers.get('Authorization')!

  const supabase = createClient(
    Deno.env.get('SUPABASE_URL')!,
    Deno.env.get('SUPABASE_ANON_KEY')!,
    { global: { headers: { Authorization: authHeader } } }
  )

  const { data: { user } } = await supabase.auth.getUser()
  if (!user) return new Response('Unauthorized', { status: 401 })

  const session = await stripe.checkout.sessions.create({
    customer_email: user.email,
    line_items: [{ price: priceId, quantity: 1 }],
    mode: 'subscription',
    success_url: `${req.headers.get('origin')}/dashboard/?checkout=success`,
    cancel_url:  `${req.headers.get('origin')}/pricing/`,
    metadata: { supabase_user_id: user.id }
  })

  return Response.json({ url: session.url })
})

Deploy it:

supabase functions deploy create-checkout \
  --project-ref YOUR_PROJECT_ID

supabase secrets set \
  STRIPE_SECRET_KEY=sk_live_... \
  --project-ref YOUR_PROJECT_ID

2.3 Add GitHub Actions secrets

In your GitHub repo → Settings → Secrets → Actions, add:

  • STRIPE_SECRET_KEY — your Stripe secret key (sk_live_...)
  • STRIPE_WEBHOOK_SECRET — from Stripe → Webhooks → your endpoint
  • SUPABASE_URL — your project URL
  • SUPABASE_SERVICE_ROLE_KEY — service role key (for admin writes)
  • RESEND_API_KEY — from Step 3

Step 3 · Resend — Email Alerts

Time: ~5 minutes · Cost: Free up to 3,000 emails/month

Resend handles your weekly distress alert emails with high deliverability.

3.1 Set up a domain

  1. Go to resend.comDomains → Add Domain
  2. Add distresssignal.email (or your domain)
  3. Add the DNS records they give you (takes ~10 min to verify)

3.2 Get an API key

Resend dashboard → API Keys → Create API Key → copy it.

3.3 Test the alert script locally

cd scripts/
pip install resend supabase
RESEND_API_KEY=re_... python send_alerts.py --dry-run

This will print the emails that would be sent without actually sending anything.


Step 4 · Deploy & Verify

Once all three sets of credentials are in place:

# 1. Rebuild the site (demo banner disappears)
hugo --minify

# 2. Push to trigger Netlify auto-deploy
git add hugo.toml
git commit -m "chore: connect live Supabase credentials"
git push origin main

Verification checklist:

  • Amber demo banner is gone from every page
  • Sign-up modal creates a real account in Supabase → Authentication → Users
  • /signup/ redirects to /reports/ after login
  • Stripe checkout redirects to Stripe’s hosted page
  • Email arrives after clicking “Subscribe” in footer

Estimated Time to Go Live

StepTime
Supabase project + migration~10 min
Stripe products + Edge Function~15 min
Resend domain verification~15 min (mostly waiting for DNS)
Rebuild & deploy~3 min
Total~45 minutes

Ready to connect credentials?
Questions about any step above? Email research@distresssignal.email
Start with Supabase →