Installation
To fully utilize DirectoryStack, you'll need to configure some third-party tools and set up corresponding environment variables. This guide will walk you through the necessary steps for each provider, which are:
- Supabase (database & auth)
- Resend (transactional emails)
- Umami.is (analytics)
- OpenAI (ai content)
- Stripe (payment)
Before we dive into the specifics, create a .env.local
(by renaming .env.local.example
) file in the root of your project. This file will store all the environment variables needed for your project.
In your local dev environment, leave NODE_ENV
as development
and when deploying, change to production
- NODE_ENV=development
Choose a secure password to protect your APIs & Webhooks, for example
- API_SECRET_KEY=213sUperSecretkEy213
Go to the file vercel.json
and change the hardcoded API_SECRET_KEY to the one you just chose.
We choose Supabase as the database provider for this project as it has a generous free-tier.
- Create a free account at Supabase and a new project: Remember the Database Password. We need it later.
- Login and in the left sidebar, click on
Project Settings
(at the bottom) - Copy the Project Reference Id (long string of letters) and paste it as the
NEXT_PUBLIC_SUPABASE_PROJECT_ID
- in the Settings Menu, click on API, and copy the Project URL and paste it as the
NEXT_PUBLIC_SUPABASE_URL
- On the same page, copy the ANON PUBLIC API KEY and paste it as the
NEXT_PUBLIC_SUPABASE_ANON_KEY
- On the same page, copy the service_role key and past it as the
SUPABASE_SERVICE_ROLE_KEY
(Never share this key anywhere (except with your hosting provider) because it can bypass supabase RLS.) - Go to the file
package.json
, and in 'scripts>typgen', replace '[ YOUR_SUPABASE_PROJECT_ID ]' with theNEXT_PUBLIC_SUPABASE_PROJECT_ID
The following variables in your .env.local should be filled now:
NEXT_PUBLIC_SUPABASE_PROJECT_ID=
NEXT_PUBLIC_SUPABASE_URL=
NEXT_PUBLIC_SUPABASE_ANON_KEY=
SUPABASE_SERVICE_ROLE_KEY=
Supabase's free tier allows for 3 transactional emails (e.g. Signup Confirmations) per hour. Generous for testing purposes, but we want to scale! That is why we chose resend.com for transactional emails because their have a generous free-tier of currently 3k transactional emails per month and are easily integratable with Supabase for auth emails. You can of course skip this part while setting it up but before launching, I highly recommend switching to Resend.
- Head over to Resend and create a free account
- Follow this guide: https://resend.com/docs/send-with-supabase-smtp (alternatively activate this integration: https://supabase.com/partners/integrations/resend)
- Disable
Click Tracking
under resend.com/domains. While we like knowing whether our links are clicked, resend is using aws click tracking under the hood which might get your emails in spam - not a great user experience. As this is merely a confirmation email, it should be fine.
We choose Umami.is as the analytics provider because it has a generous free-tier and is GDPR / CCPA compliant without setting cookies (e.g. you will not need any Cookie Banner!)
- Create a free account at Umami.is.
- Click on
+ Add website
and provide your website name and the final domain. E.g. "Name: DirectoriesHQ" , "Domain: directorieshq.com" (no https) - CLick on
Edit
and copy theWebsite ID
The following variables in your .env.local should be filled now:
NEXT_PUBLIC_UMAMI_ID=
We use OpenAI to create embeddings for the listings (AI-powered Semantic Search!), and for the "Ai Content Generation Buttons" (like to tags, categories, blog posts and listing descriptions).
There will be API costs associated with it!
This template uses the new and cheap gpt-4o-mini
model. As per openai.com the current costs are US$0.15 / 1M tokens (input) and US$0.6 /
1M tokens (output). For a test project, we clicked the listing-button 70 times (aka 70 descriptions and excerpts) and used 25k tokens (40% Input & 60% Output) which resulted in costs of US$0,0015 (input) and US$0,009 (output) so in rouhgly US$0,0105 (Yes, roughly 1 cents). As an example, head over to the test project DomainersKit / Domainhacks.info and read the excerpt (the short description) and then the long text (the long description). This is what you'll get.
- Create an account at openai.com
- On the left sidebar, click on
API Keys
. - Click on
+ Create new secret key
- Give it a name and set the permissions to
Restricted
and allowWrite
for theModel capabilities
. Then hitCreate secret key
. - Copy the newly created key and paste it to your
.env.local
as theOPENAI_API_KEY
The following variables in your .env.local should be filled now:
OPENAI_API_KEY=
If you do not set the three Stripe keys, the user will see a "Write us an email to promote your listing" notification instead of a self-signup form.
It is advisable to perform the steps 2-7 in "Test Mode" first before going live. The toggle is in the top right menue.
- Create a free account at Stripe
- Follow the onboarding flow and setup your account.
- Go to https://dashboard.stripe.com/settings/tax and activate automated tax calculations. If you don't want to use this feature, go to the file
createStripeCheckoutSession.ts
and remove the lineautomatic_tax: { enabled: true },
fromconst session = ...
. - Click on
Developers
in the top menu and then onAPI keys
. Copy the publishable key as theNEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY
. - On the same page, copy the Secret Key and add it as the
STRIPE_SECRET_KEY
- Still in the developer menue, click on
Webhooks
(right next toAPI keys
), and create a new endpoint (https://YOURDOMAIN.com/api/payment/stripe-receipt). (If you want to test it locally, use the Stripe CLI, follow the steps in the Stripe docs). - In the webhhook menue for this custom webhook, click on
Signing Secret Reveal
and copy this value as theSTRIPE_WEBHOOK_SECRET
.
This was the setup of the Stripe account. While you are on this page,
- Create a new product by heading to the
product catalogue
and clicking the buttonAdd product
. - Name it
Promoted Listing
, give it a ONE-TIME price of USD 1.00 (or whatever your price shall be for a listing to be promoted for 1 day.) - In the top-right corner of the product page, copy the
product id
which starts with 'price_' and paste it to the fileapp/constants/constants.ts
as theSTRIPE_PRICE_ID
where we definePROMOTIONS_DATA
. - Next, again in the
product catalogue
on Stripe.com, click onCoupons
and add a new coupon. This will be the automatic discount for when a user buys more than 30 days of promotions. E.g. create a 10% discount code, with duration forever. Once created, you'll need to copy theID
which you find underDetails
. IGNORE the API ID of the coupon, which is NOT needed here. TheID
is a lot short than the API ID. Add this coupon as theSTRIPE_COUPON_ID
to thePROMOTIONS_DATA
to the fileapp/constants/constants.ts
.
The following variables in your .env.local should be filled now:
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=
STRIPE_SECRET_KEY=
STRIPE_WEBHOOK_SECRET=