Installation and deployment
From download to production: requirements, Firebase, Stripe and the deploy, in order.
From download to production. The order matters: configure Stripe before you have Firebase and you cannot test anything end to end.
Requirements
- Node.js 22 or newer. Not a preference:
firebase-admin14 requires it in its ownpackage.json. On Node 20 the install warns you and something will eventually break. - A Firebase project with Authentication, Firestore and Storage.
- A Stripe account.
- A transactional email provider.
1. Install
npm install
cp .env.example .env.local
Fill .env.local following the comments in .env.example. Every key is
explained one by one in Environment variables.
Only variables prefixed NEXT_PUBLIC_ reach the browser. Everything else stays
on the server. When in doubt about one, that is the rule.
2. Firebase
- Create the project and a web app, and copy its configuration into the
NEXT_PUBLIC_FIREBASE_*variables. - Enable Authentication (email and password, plus any providers you want).
- Create Firestore and Storage.
- Generate a service account key and fill in the admin variables.
- Deploy the rules and indexes that ship with the template.
You do not have to write the rules from scratch: firestore.rules,
storage.rules and firestore.indexes.json are in the repository root, wired
through firebase.json.
npm i -g firebase-tools
firebase login
firebase use <your-project-id>
firebase deploy --only firestore:rules,firestore:indexes,storage
The composite indexes are not optional. Without them the admin panel and the support inbox fail their queries, and the error shows up in production, not at build time. To check against your real project:
npm run verify:indexes
That command does not trust the file: it runs the real queries and tells you which ones the database refuses.
What the shipped rules open
The rules deny everything by default and then open two things to the
browser: the user's own users/{uid} document, and reading and creating their
own credit_purchases. Everything else (webhook logs, rate limits, the GDPR
deletion log, the security audit, the documentation) is server-only, through the
Admin SDK, which bypasses rules by design.
When you add collections for your product, write their rules. Anything you add without a rule falls into the final deny: safe, but it will not read from the browser until you write it.
3. Stripe
- Create your products and prices (the credit packs) and wire their IDs into the purchase flow.
- Put the publishable and secret keys in
.env.local. - Create a webhook pointing at
/api/webhookand copy its signing secret into.env.local.
That is the route the template exposes (src/app/api/webhook/route.ts). It
verifies signatures and is idempotent. A webhook pointed anywhere else returns
404, and then your customer pays and never receives their credits. Check the
path before you open to the public.
4. Run locally
npm run dev # http://localhost:3000
npm run verify:all # the day-to-day gate
npm run build # production build
verify:all starts no server. Before publishing, use the full one, which adds
the browser tests:
npm run verify:release
5. Deploy
- Push the repository to your Git provider and import it into your deployment platform (framework: Next.js).
- Add every variable from
.env.localas an environment variable, in production and preview. SetNEXT_PUBLIC_BASE_URLto your real URL. - Deploy. Then move the Stripe webhook to the production URL and set the production signing secret.
- Point your domain and confirm
NEXT_PUBLIC_BASE_URLmatches it. Search visibility, the sitemap, the emails and the legal links all depend on it.
Any Node host works.
6. Before you open to the public
- [ ] No secrets in the repository;
.env.localis git-ignored. - [ ] Firestore and Storage rules deployed and extended with your product's collections.
- [ ] Indexes deployed;
npm run verify:indexesgreen against the production project. - [ ] The Stripe webhook points at
/api/webhookon the production domain, with the production secret, and a test event arrives. - [ ] Legal texts reviewed by a professional and company data filled in.
- [ ] Brand, colours, copy and images replaced.
- [ ]
npm run verify:releaseandnpm run buildgreen.