Build and Deploy a Membership Website With Claude Code

Build a real membership website with protected content, member accounts, and an admin dashboard, then deploy it live on Hostinger.

Roadmap & Resources

Build Your Membership Website

Choose Your Membership Setup

Open an empty folder — or your existing project — in Claude Code. Pick your membership type first: the content types then suggest the mix that fits it.

Build Your Membership Website

Choose your membership type, what members get and your homepage message, and Claude Code builds the public site, member area and admin screens with realistic sample content.

Build the interface for a membership website. This task builds the screens only, with realistic sample content. Accounts and real data come later. Membership type: {{MEMBERSHIP_TYPE}} Membership name: {{MEMBERSHIP_NAME}} What members get: {{CONTENT_TYPES}} What the membership is, in one sentence: {{SHORT_DESCRIPTION}} Who it is for: {{TARGET_AUDIENCE}} Why someone should join: {{MAIN_BENEFIT}} Visual style: {{VISUAL_STYLE}} Access: free membership. Anyone who creates and confirms an account becomes a member. No pricing, payments or Stripe. 1. INSPECT FIRST Inspect this folder before changing anything. - If it is empty, create a new React + Vite + TypeScript project here, with client-side routing and a simple, well-organised structure. - If a project already exists, keep its framework, styling and components, and add the membership website to it. Do not rebuild, rename or restructure working code, and do not touch unrelated pages. Tell me which case applies, then continue. 2. SAVE THE MEMBERSHIP SCOPE Add a "Membership" section to CLAUDE.md in the project root — create the file if it does not exist. Record the membership type, the name, the content types, the homepage message, the visual style and that membership is free. Every later task reads this section, so keep it short and accurate. Never write keys or passwords into it. 3. KEEP THE SCOPE FOCUSED This is a membership website: a public site, member accounts, protected content and admin management. Do not add chat, forums, courses or progress tracking, client projects, complex roles, payments, messaging, live events or gamification. This version supports six content types: articles and guides, downloadable resources, videos, templates, links and tools, and private updates. Build only the ones listed above. If I listed another type, use the closest supported one and tell me. 4. PUBLIC WEBSITE - a homepage that says who the membership is for, what members get and why to join, with a clear Join call to action - How It Works or About — only if it genuinely helps - sign-up and sign-in screens — the design only, they do not need to work yet No extra marketing pages. 5. LOCKED CONTENT Visitors should understand what membership unlocks — for example titles and short teasers with a clear "Members only" state. Never put the protected content itself on a public page and hide or blur it with CSS. 6. MEMBER AREA It must feel different from the marketing site: a calm, app-like area with its own navigation. - a dashboard with a welcome, the latest content, a featured item and recently added items — no fake analytics - a library with only the chosen content types, and categories where they help - a page for each item - an account page Show navigation items only for the chosen content types — for example Library, Videos, Templates, Updates and Account. 7. ADMIN AREA Build a separate owner area: a content list with Draft and Published states, a create and edit form with only the fields the chosen types need, and a simple member list. The forms can stay local for now. Never pretend that something was saved. 8. SAMPLE CONTENT Create realistic sample content for this membership: 8 to 12 items across the chosen types, in 3 to 5 categories. No lorem ipsum. Keep all sample content in ONE clearly named module, shaped like real data, so a database can replace it later. 9. PREVIEW SWITCH Until real sign-in exists, add one small, clearly labelled switch between the visitor, member and admin views. Keep it in one place so it is easy to remove. 10. DESIGN Apply the visual style and the name. The site must work well on phones, tablets and desktops. Keep it calm: no decorative gradients or glows and no fake statistics. 11. RUN IT Start the development server and give me the local address. When finished, report: - whether you created a new project or extended an existing one - the public, member and admin screens - how locked content looks to visitors - where the sample content lives - anything you left out, and why

What kind of membership website are you building?

Website or membership name

Creator Vault

What should members get access to?

Visual style

Describe the membership in one sentence

A private library of templates and guides for freelance designers

Who is it for?

Freelance designers and content creators

Why should someone join?

Save hours every week with ready-to-use templates

Claude Code saves your choices in the project's CLAUDE.md file, so every later prompt builds only what you picked.

Check the Membership Website

Open the local address Claude Code gives you and use the preview switch to look at each side:

The homepage says who it's for, what members get and why to join

The Join button is easy to find

Locked content shows a clear Members only state — never blurred content

The member area looks and feels different from the public site

Member navigation shows only the content types you chose

The admin screens show the content list, the content form and members

Everything works at phone width

Ask Claude Code for any change now — the interface is easiest to adjust before real data arrives.

Expected result

You should now have a polished public membership website plus a complete sample member and admin interface running locally.

Add Real Member Accounts & Protected Access

Connect Supabase

If this project is already connected to the right Supabase project, reuse it — don't create a second one.

Open Supabase

https://supabase.link/r4gdwhi

Create a new project if you don't have one Open the project's Connect panel Copy the Project URL and the Publishable key Ask Claude Code which environment variable names this project uses, then add both values locally

IMPORTANT

The browser app only needs the Project URL and the Publishable key. A Secret key belongs only in a trusted server environment, and only where one is genuinely needed — never in browser code and never committed to GitHub.

Point confirmation links at your app

Set the Site URL to the local address Claude Code gave you in Step 1 — for example http://localhost:5173 — so sign-up confirmation links open your app. You'll switch it to your live address when you deploy.

Supabase Authentication URL Configuration

Create Two Test Members

Member A and Member B are test accounts for checking privacy. You'll create your own account through your website's real sign-up in the next step.

Supabase Authentication Users

Click Add user, then Create new user Enter the email address and a password Keep Auto Confirm User on, then create the user Repeat for Member B

Use email addresses you control.

Add Real Accounts and Protected Access

Use this prompt in Claude Code. It gives you one SQL block to run now and one statement to run after you sign up.

Add Member Accounts and Protected Access

Add sign-up, sign-in and sign-out, the member and admin roles, and protected member and admin areas that the database enforces.

Add real member accounts and protected access with Supabase. Read the "Membership" section of CLAUDE.md first. Inspect the project first. If it is already connected to Supabase, reuse that project and its client — do not create a second one. Use the current Supabase terms: the Project URL and the Publishable key. Never put a Secret or service-role key in browser code, and never print secret values. 1. ENVIRONMENT Read the Project URL and the Publishable key from environment variables, using this framework's naming. Tell me the exact names, list them in .env.example without values, and make sure .env is git-ignored. 2. SIGN-UP, SIGN-IN AND SIGN-OUT Use email and password with Supabase Auth, following the current documented pattern for this framework. - Keep email confirmation on. After sign-up, show "Check your email to confirm your account", and send the confirmation link back to this app's own address — never a hard-coded one. - Handle sign-in after confirmation, sign-out, and an expired session cleanly. - Remove the preview switch. From now on, the signed-in account decides what appears. 3. MEMBERS Membership is free: every confirmed account becomes an active member automatically. - Keep a profiles table keyed by the auth user id. Create a profile for every new account — role member, status active — and backfill profiles for the accounts that already exist. - Store a display name and the joined date. No billing or subscription fields. - A member can read and update only their own profile, and never their role or status. 4. ADMIN There are exactly two roles: member and admin. Do not build a general roles-and-permissions system. - Nobody can change their own role. Never decide it from user_metadata, local storage, the URL or anything else the browser controls. - Give me ONE separate, reviewed SQL statement that makes MY account the admin by its user id. I will run it after I sign up. 5. PROTECTED ROUTES - Public: the homepage, public pages, sign-up and sign-in - Members only: the dashboard, the library, content pages and the account page. A signed-out visitor is sent to sign in. - Admin only: content and member management. A member sees "no access". Route guards shape the experience, but the database is the protection: member data is never sent to a signed-out visitor, and admin data never to a member. 6. ACCESS RULES Turn on Row Level Security on every table immediately. Use one trusted database check for "is this account an active member" and one for "is this account the admin". A suspended member counts as not a member. The real library comes next. Keep the sample content in place for now, shown only in the member area. Give me: 1. The environment variable names 2. The tables and what each holds 3. How roles and status are stored and protected 4. ONE reviewed SQL block to run in the Supabase SQL Editor: the tables, the rules, the profile creation and the backfill 5. The separate admin statement 6. Anything that blocks the next step Do not use destructive DROP statements. If a table with the same name already exists, warn me instead of replacing it.

Review the SQL block, then run it in your Supabase project.

Supabase SQL Editor

Sign up as the owner

Sign up on your website with the email address of your Supabase account, then confirm it from your inbox. Until you connect your own email provider in Step 6, Supabase's built-in email only reaches your own team's addresses.

You land in the member area as a new member

The admin area is refused

Now make your account the admin: run the single statement Claude Code gave you in the SQL Editor, then sign in again.

The admin area opens

Member A: sign in — the member area opens and the admin area is refused

Sign out — member pages send you back to sign in

Expected result

A real user can now create an account, sign in, access the member area, and remain blocked from admin-only pages.

Build the Members-Only Content Library

Build the Content Library

Build the Members-Only Library

Store your chosen content types for real, keep everything but short teasers private to members, and serve files through private links.

Build the members-only content library with real data. Read the "Membership" section of CLAUDE.md first, and support only the content types it lists. Every read goes through the database rules. No Secret or service-role key in the app. 1. CONTENT DATA Use one content table with only the fields the chosen types need — for example a title, a slug, a short teaser, the type, the category, the body, a video URL, a link URL, a file reference, a thumbnail, a draft or published status, published_at, created_at and updated_at. Leave out anything unused. Add categories only if they help this membership. 2. PUBLIC TEASERS, PRIVATE CONTENT Visitors may see only what shows what membership unlocks: the title, the type and the short teaser of published items. Everything else — the body, video links, link URLs and files — is for active members only. Row Level Security works per row, so keep the public teaser where the rules can separate it — for example in its own table, or behind a trusted function that returns only those fields. Never send protected content to a public page. 3. DRAFTS AND ACCESS Active members read published content. Drafts are visible only to the admin. Suspended members and signed-out visitors read nothing protected — the database enforces this, not the screen. 4. CONTENT TYPES — only the chosen ones - Articles and guides: readable long-form text — for example Markdown rendered safely, with no raw HTML. - Videos: store a normal video URL from a host such as YouTube, Vimeo or Bunny Stream — never pasted embed HTML — and show it in an embedded player. Do not build video hosting. Say plainly in your report that anyone with an unlisted link can share it. - Downloadable resources and templates: files in a PRIVATE Storage bucket, downloaded only by active members through short-lived signed URLs that expire within a few minutes. Never make member files public because direct links are easier. - Links and tools: a title, a description and a destination URL — http or https only. - Private updates: short posts shown in the member dashboard, newest first. 5. THE LIBRARY Members browse the library, filter by category or type where it helps, open an item and download what they are allowed to. Add search only if there will be enough content to need it. 6. REAL DATA Replace the sample content with real queries, and remove the sample module. Give me ONE reviewed SQL seed that recreates the sample content in Supabase — mostly published, plus one draft — without file rows for files that do not exist yet. Give me ONE reviewed SQL block to run in the Supabase SQL Editor for the tables, the rules, the private bucket if needed and the seed. Never drop tables, columns or data. When finished, report: - the content fields for each chosen type - what a signed-out visitor can and cannot read - how files are stored and downloaded - the video-link limitation, in plain words

Review the SQL it gives you, then run it in the SQL Editor.

IMPORTANT

Videos use a link from a host such as YouTube or Vimeo. Visitors without access never see it, but anyone who has an unlisted link can share it. If that matters, use your video host's privacy settings — for example allowing embeds only on your own domain.

Test the Member Library

Sign in as Member A:

The library shows the published sample content

The draft item doesn't appear

Each content type you chose opens correctly

Filtering by category or type works, where you have it

Signed out: a member content address sends you to sign in

Expected result

Members can now browse real protected content and access the resources included in their membership.

Build the Admin Content Manager

Manage Content in the Website

Build the Admin Content Manager

Create, preview, publish and delete member content and upload files from your own admin area instead of Supabase.

Make the admin content manager work, so I publish everything inside the website. I must never need the Supabase dashboard for normal publishing. Read the "Membership" section of CLAUDE.md first, and show only the fields the chosen content types need. Reuse the admin screens you already built. Every write goes through the database rules, which allow admin actions only. No Secret or service-role key in the app. 1. ADMIN ONLY Only the admin account reaches the admin area. Members and signed-out visitors see "no access" or the sign-in screen, and the database refuses their requests anyway. 2. CONTENT - a list of all content with its status, type and category - create and edit an item: the title, teaser, type, category and the fields that type needs - Preview: see a draft exactly as members will see it - Publish and Unpublish — unpublished content leaves the member library - Delete or archive only after a clear confirmation; deleting also removes the item's file 3. FILES — only for downloadable resources or templates Upload files through the app into the private bucket, with allowed file types, a sensible size limit and one folder per content item. Replace or remove a file from the item's form. 4. VIDEOS — only if chosen Enter a supported video URL. Never upload large video files to Supabase. 5. CATEGORIES — only if used Create, rename and delete categories. Ask before deleting a category that is still in use. 6. FORMS Validate required fields and sensible lengths, accept only http and https links, prevent double submission, show clear success and error messages, and never show raw database errors. Keep every screen usable on a tablet and a phone. Give me ONE reviewed SQL block for any new rules or buckets, to run in the Supabase SQL Editor. Never drop tables, columns or data. When finished, report: - the admin routes - how the admin check works in the app and in the database - what Preview shows - how uploads are validated and stored

Run any SQL it gives you in the SQL Editor. Then, as the admin:

Create a draft and preview it

Publish it — Member A sees it in the library

Edit it — members see the change

Unpublish it — it leaves the member library

Upload a file to a downloadable item — Member A can download it

Delete a test item — you're asked to confirm first

See and Manage Members

Add the Member List

See your members and their joined dates, and suspend or restore a member's access without deleting their account.

Add a lightweight member view to the admin area. Read the "Membership" section of CLAUDE.md first. 1. MEMBERS Show each member's name or email, joined date and status — active or suspended — through an admin-only path. No CRM and no analytics. 2. SUSPEND AND RESTORE Let me suspend a member: they keep their account but lose access to member content, because the database treats a suspended member as not a member. Let me restore them later. Do not delete authentication users as the normal way to remove a member. 3. ADMIN ONLY Only the admin can see this list or change a status, and the database enforces it. Give me ONE reviewed SQL block for any new rules or database functions, to run in the Supabase SQL Editor. When finished, report: - what the member list shows - how suspension is enforced - what a suspended member sees

Run any SQL it gives you, then check:

See Member A and Member B with their joined dates

Suspend Member B — after a refresh, Member B loses access to member content

Restore Member B — access returns

Expected result

The owner can now create and publish member-only content entirely through the website's admin dashboard.

Test the Complete Membership Experience

Test as a Visitor and a Member

Start signed out, then use Member A. Skip any check for a content type you didn't choose.

Visitor: the homepage works

Visitor: the membership benefits are clear

Sign-up: a mistyped email or a short password shows a clear message

Member A: sign-in works

Member A: the dashboard opens

Member A: published content appears

Member A: draft content does not appear

Member A: each content type you chose works

Member A: private downloads work

Sign out — the member area is closed again

Test the Admin and Two Members

Use the admin account, then Member A and Member B in two browsers.

Admin: create content

Admin: edit it

Admin: publish it

Member A: sees the published content

Admin: unpublish it — it leaves the member library

Admin: file uploads work

Admin: preview shows a draft as members will see it, while members still can't

Member A and Member B stay signed in separately in two browsers

Member B's account page shows only Member B's details

Account details save correctly

Test Privacy and Quality

Run these by hand, then let Claude Code check the database directly:

Signed out: member pages send you to sign in

Member A: the admin area is refused, even by typing its address

An empty library section shows a helpful message

Loading states appear while content loads

Errors are easy to understand

Mobile navigation works

The member dashboard works on a phone

Refreshing a member or admin page keeps you there

Verify and Fix the Membership Website

Prove the access rules directly in the database as a visitor, a member and a suspended member, then fix only the checks that failed.

Verify this membership website at the database level, then fix what failed. Read the "Membership" section of CLAUDE.md first, and test only the content types it records. These manual checks failed: {{FAILED_CHECKS}} 1. DATABASE CHECK Use a temporary LOCAL-ONLY script with the project's normal Supabase client and the Publishable key. Do NOT use the Secret or service-role key: it skips every access rule, so the test would prove nothing. Ask me to put the test accounts' passwords in local, uncommitted environment variables. Never commit passwords, never put them in source code and never print them. As a SIGNED-OUT visitor, try to: - read protected content — bodies, video links, link URLs — including by an exact id or slug - read drafts - list or download member files, including by a guessed path - read any profile As MEMBER B, try to: - read Member A's profile - change their own role or status - create, edit, publish or delete content or categories - upload, replace or delete files - read drafts As a SUSPENDED member — suspend Member B through the admin path, then restore them afterwards — try to read protected content. Expected: refused — an error, no rows returned or zero rows changed. Re-read afterwards to confirm nothing changed. As MEMBER A: read published content and download an allowed file. Expected: it works. As the ADMIN: create, edit, publish and delete a test item. Expected: it works. Remove it afterwards. 2. SECRETS Search the source code and the built files. Only the Supabase Project URL and Publishable key may appear. 3. FIX Find the real cause of each failed check — mine and yours — and fix it at its source. Keep every fix small: no redesign, no new features and no rewrites of working code. Run the database check again after any fix. Remove the script afterwards and do not commit it. Return exactly one: MEMBERSHIP READY or: NEEDS ATTENTION If NEEDS ATTENTION, give me any corrected SQL to run, list what still fails, and test again once I confirm the SQL has run.

Which checks failed?

Member B still sees content after being suspended. The menu doesn't close on a phone...

Continue when Claude Code reports MEMBERSHIP READY. Its report confirms:

Signed-out visitors can't read protected content directly

Signed-out visitors can't download member files

Members can't publish or edit content

Changing anything in the browser doesn't grant admin access

No secret keys reach the browser

Expected result

Visitors can join, members can access protected resources, and the owner can manage everything through a secure admin area.

Deploy the Membership Website to Hostinger

Prepare and Deploy the Website

Prepare the Membership Website for Production

Build for production, remove development leftovers, keep secrets out, and make member pages survive a refresh on Hostinger.

Prepare this membership website for production on Hostinger, as a Node.js Web App deployed from GitHub. Read the "Membership" section of CLAUDE.md first. Do not add features, and never print secret values. 1. BUILD Run the production build and fix anything that fails. 2. REMOVE DEVELOPMENT CODE Remove anything left from development in the code: leftover sample content, the preview switch, test-only scripts, debug logging and any hard-coded test account. Sample content in the database stays until I remove it myself. 3. NO SECRETS IN THE APP Search the source code and the built files. Only the Supabase Project URL and Publishable key may appear — no Secret or service-role key and no passwords. Make sure .env is git-ignored and never committed, and that .env.example lists the variable names without values. 4. ENVIRONMENT VARIABLES List the exact environment variable names Hostinger needs, and whether this framework needs them at build time. 5. LIVE ADDRESSES Nothing may point at localhost in production. Build the sign-up confirmation link and every other redirect from the live address, never a hard-coded URL. 6. PAGE REFRESH Member, content and admin pages use client-side routes. Refreshing or directly opening any of them on Hostinger must load the app and keep the session, not show a 404. Set this up the way Hostinger's Node.js Web App serves this framework — for example a small production server with a fallback to the app. 7. HOSTINGER SETTINGS Tell me what to confirm on Hostinger's deploy screen: the framework, build command, output directory, Node version and, if one is needed, the entry file. Do not commit or push — I will review first. Report: - the build result - what you removed - the environment variable names - how page refresh is handled - the Hostinger settings - anything that blocks deployment

Push the project to GitHub with Claude Code or your normal GitHub workflow. If it already has a repository, use it.

Deploy on Hostinger

Recommended plan: Business

USED IN TUTORIAL

https://www.hostg.xyz/SHK1P

Hostinger Websites Add Website Node.js Web App

Choose Import Git repository Connect GitHub and select the website's repository Confirm the framework and build settings Claude Code gave you Add the environment variables with your project's exact names Click Deploy and wait for the result

IMPORTANT

Add the Supabase Project URL and Publishable key under the names your project already uses. Private server keys stay private — never rename one to a VITE_ or NEXT_PUBLIC_ variable to make the deployment work.

Fix a Failed Website or Web App Deployment with AI

Use this if the Hostinger deployment fails.

/video/fix-a-failed-website-or-web-app-deployment-with-ai

Set Up Production Sign-Up

New members can only join on your live address once Supabase knows it, and they need real confirmation emails.

1. Switch to your live address

Set the Site URL to your live Hostinger address and add it to the Redirect URLs.

Supabase Authentication URL Configuration

2. Keep Confirm email on

Open Email and make sure Confirm email is on, so every member account belongs to a real inbox.

Supabase Authentication Sign In / Providers

3. Send emails from your own domain

Supabase's built-in email only reaches your own team's addresses, two emails an hour, so new members would never receive their confirmation email. Choose a provider such as Resend, Postmark, Amazon SES or Brevo, verify your domain there and create SMTP credentials. Then turn on Enable Custom SMTP and enter the sender email, sender name, host, port, username and password.

Supabase Authentication Emails SMTP Settings

Keep SMTP credentials in Supabase

Your SMTP password lets anyone send email as your domain. Enter it only in Supabase's SMTP settings — never in the app, an environment file, the repository or a Claude Code conversation.

Test the Live Membership Website

Open your live address and check:

The homepage loads on your Hostinger address

New member: sign up with a real email address and confirm it from the inbox

New member: sign in

The member dashboard loads

Published member content loads

Protected downloads work

Signed out: member pages stay blocked

Admin: sign in

Admin: create or update content

The published change appears to members

Draft content stays private

A copied member content address stays protected when signed out

The website works on a phone

Verify the Live Membership Website

Check the deployment, production sign-up, protected content and files, and secrets on the live website.

Perform a focused production check of this membership website, now live on Hostinger. Read the "Membership" section of CLAUDE.md first. Do not add features and never print secret values. Do not claim to inspect Hostinger or Supabase settings you cannot see — ask me for the live address, and ask me to confirm specific settings. 1. DEPLOYMENT - the deployment succeeded from the intended repository and branch - the required environment variables are set - no secret files are in the repository 2. SIGN-IN - the Supabase Site URL and Redirect URLs use the live address - Confirm email is on, and custom SMTP sends the confirmation emails - sign-up confirmation, sign-in and sign-out use the live address, never localhost - refreshing a member or admin page keeps the session and never shows a 404 3. ACCESS - run the signed-out, Member B and suspended-member database checks against the production Supabase project, with the Publishable key — never the Secret or service-role key - drafts, protected content and member files stay private - only the admin reaches the admin area 4. SECRETS - no secret key appears in the live site's code or network requests Return exactly one: MEMBERSHIP LIVE or: NEEDS ATTENTION If MEMBERSHIP LIVE, summarize the live address, sign-up, the member area, protected content and files, and the admin area. If NEEDS ATTENTION, list only launch blockers.

Continue when Claude Code reports MEMBERSHIP LIVE, confirming:

No secret keys appear in the live site's code or network requests

Before real members join

Unpublish or delete the sample content in your admin area, then delete the Member A and Member B accounts in Supabase. Keep your own admin account.

Supabase Authentication Users

Expected result

Your membership website is live on Hostinger with real member accounts, protected content, private resources, and a secure admin dashboard.