GoFarm Docs · v1.0 · Next.js 16

GoFarm Developer Documentation — Build, Configure & Ship

The complete reference for the GoFarm agricultural e-commerce platform. This guide walks you through everything from cloning the repo to deploying on Vercel — installation, service configuration, architecture, schemas, APIs, payments, analytics, and the coding standards every contributor follows.

Stack: Next.js 16 · React 19 · TypeScript 6CMS: Sanity 5 · Auth: FirebasePackage manager: pnpmLicense: MIT
Get started in 5 minutespnpm install  →  cp .env.example .env.local  →  pnpm devClone, install, copy the env template, fill in your service credentials, and run. The full step-by-step is in §5.

01Introduction

GoFarm is a production-ready agricultural e-commerce platform that connects farmers and consumers directly. It ships with a full storefront, an admin dashboard, vendor onboarding, an employee portal, multi-currency support, Stripe + SSLCommerz checkout, and a Sanity-powered CMS.

The codebase is built around three principles: a single source of truth per concern (Firebase Auth for identity, Sanity for domain data, GA4 for analytics), server-by-default React components, and strictly enforced coding standards via Biome, lefthook, and Conventional Commits.

Who this guide is for

  • New contributors setting up a local environment for the first time.
  • Maintainers looking for a complete reference to the routes, APIs, and schemas.
  • DevOps engineers deploying GoFarm to Vercel or another host.
  • Store operators configuring services (Sanity, Stripe, email) before going live.
Read this first. If you only have time for one section, jump to §5 Quick Start. Then come back for §7 Service Setupwhen you need real credentials. Want me to install & configure it for you? See §23 Pricing & Hire Me.

02Tech Stack

GoFarm uses a modern, battle-tested set of libraries. Every package is on a current major version with security patches applied.

LayerTechnologyVersionPurpose
Frameworknext16.2.xApp Router, React Server Components, Turbopack
UIreact / react-dom19.2.xServer Components, Actions, Suspense
Languagetypescript6.0.xStrict mode + noImplicitOverride
Stylingtailwindcss4.2.xUtility-first CSS with theme tokens
ComponentsRadix UI + shadcn/ui1.xAccessible primitives
Animationmotion12.38.xPage and component transitions
CMSsanity / next-sanity5.21.xHeadless content + embedded Studio
Authfirebase / firebase-admin12 / 13Email + OAuth, 14-day session cookies, custom claims
Paymentsstripe + SSLCommerz22.xCard, wallet, BDT, COD
Emailnodemailer8.xGmail OAuth2 transactional email
Statezustand5.xAuth, cart, wishlist, compare, share
Formsreact-hook-form + zod7.x / 4.xSchema-first input validation
ToolingBiome v2, lefthook, commitlintFormat, lint, hooks, commit policy
Server-firstEdge-readyPCI-safe checkoutGA4 e-commerce

03Core Features

Out of the box, GoFarm includes everything an agricultural marketplace needs. The full feature set is available to anyone using or purchasing the project — there are no locked tiers.

Storefront

  • Multi-image product catalog
  • Category, brand, and collection pages
  • Product variants (size, color, weight)
  • Real-time inventory tracking
  • Search, filters, and faceted browse
  • Status badges (New, Hot, Featured)

Cart & Checkout

  • Persistent cart synced across sessions
  • Wishlist + compare list
  • Discount codes and coupons
  • Stripe, SSLCommerz, Cash-on-Delivery
  • Apple Pay / Google Pay ready
  • Order confirmation emails

User Accounts

  • Firebase email + Google OAuth
  • Profile, addresses, preferences
  • Order history & tracking
  • Digital wallet + transactions
  • Loyalty & reward points
  • Reviews and ratings

Admin Dashboard

  • Product, order, and user management
  • Vendor approval workflow
  • Analytics & sales dashboards
  • Email campaigns / newsletter
  • Review moderation
  • Coupon & subscription management

Vendor Portal

  • Vendor application + approval
  • Vendor product management
  • Sales analytics
  • Wallet withdrawals
  • Commission tracking

Operations

  • Employee portal for fulfilment
  • Order workflow: Pending → Delivered
  • Newsletter & subscribers
  • Contact form + ticketing
  • Store-settings dashboard

04Prerequisites

Before you clone the repo, make sure your machine has the following installed.

ToolMinimumInstall
Node.js18.0+ (LTS 20 recommended)nodejs.org
pnpm9.0+npm i -g pnpm
Git2.30+git-scm.com
Stripe CLI (optional)latestbrew install stripe/stripe-cli/stripe

Required accounts

You will need free-tier accounts for the following SaaS services. All can be created in under 10 minutes.

05Quick Start

These five steps take you from a blank machine to a running local dev server. Detailed configuration is covered in §7.

1

Clone the repository

git clone https://github.com/noorjsdivs/gofarm.git
cd gofarm
2

Install dependencies with pnpm

The prepare script automatically installs lefthook git hooks during install.

pnpm install
3

Copy the environment template

cp .env.example .env.local

Open .env.local and fill in your service credentials. Full reference in §6.

4

Start the dev server

pnpm dev          # webpack (default)
pnpm dev:turbo    # turbopack (faster HMR)
5

Open the app

  • Storefront: http://localhost:3000
  • Sanity Studio: http://localhost:3000/studio
  • Admin panel: http://localhost:3000/admin
  • These docs: http://localhost:3000/docs
First-time install hint. If pnpm warns about ignored build scripts, just run pnpm install again. The allowlist lives under pnpm.onlyBuiltDependencies in package.json.

06Environment Variables

Every variable the app reads is grouped by concern. Server-only variables have no NEXT_PUBLIC_ prefix and never ship to the browser.

Base & admin

NEXT_PUBLIC_BASE_URL=http://localhost:3000
ADMIN_EMAILS=you@example.com,team@example.com

Sanity CMS

NEXT_PUBLIC_SANITY_PROJECT_ID=xxxxxxxx
NEXT_PUBLIC_SANITY_DATASET=production
SANITY_API_TOKEN=sk_write_token_here
SANITY_API_READ_TOKEN=sk_read_token_here

Firebase client (public)

NEXT_PUBLIC_FIREBASE_API_KEY=AIzaSy...
NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN=your-project.firebaseapp.com
NEXT_PUBLIC_FIREBASE_PROJECT_ID=your-project-id
NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET=your-project.firebasestorage.app
NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID=123456789
NEXT_PUBLIC_FIREBASE_APP_ID=1:123:web:abc
NEXT_PUBLIC_FIREBASE_MEASUREMENT_ID=G-XXXXXXXXXX

Firebase Admin (server only)

FIREBASE_PROJECT_ID=your-project-id
FIREBASE_CLIENT_EMAIL=firebase-adminsdk-...@your-project.iam.gserviceaccount.com
FIREBASE_PRIVATE_KEY="-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----\n"

Stripe

STRIPE_SECRET_KEY=sk_test_...
STRIPE_WEBHOOK_SECRET=whsec_...
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=pk_test_...

SSLCommerz (optional, BD)

SSLCOMMERZ_STORE_ID=...
SSLCOMMERZ_STORE_PASSWORD=...
SSLCOMMERZ_IS_LIVE=false

Email (Gmail OAuth2)

GOOGLE_CLIENT_ID=123456789-xxx.apps.googleusercontent.com
GOOGLE_CLIENT_SECRET=GOCSPX-xxx
GOOGLE_REFRESH_TOKEN=1/04...
SENDER_EMAIL_ADDRESS=noreply@yourdomain.com

Analytics (GA4 Measurement Protocol)

GA4_MEASUREMENT_ID=G-XXXXXXXXXX
GA4_API_SECRET=abc123...
Never commit secrets. The repo's .gitignore excludes .env* files. If a secret leaks, rotate it immediately and use git filter-repo to scrub history before pushing.

07Service Setup

Detailed walkthrough for each external service GoFarm depends on. Complete these before running pnpm dev.

7.1 Sanity CMS

  1. Sign in at sanity.io/manage and create a new project.
  2. Note the Project ID and use production as the dataset name.
  3. Under API → Tokens, generate two tokens: Editor (write) and Viewer (read).
  4. Add the CORS origin http://localhost:3000 (and later your production domain) with credentials enabled.
  5. Paste IDs and tokens into .env.local (see §6).
  6. Visit /studio to start authoring categories, brands, and products.

7.2 Firebase Authentication & Analytics

  1. Create a project at Firebase Console.
  2. In Authentication → Sign-in methods, enable Email/Password and Google.
  3. In Project settings → General, register a Web app and copy the SDK config into the NEXT_PUBLIC_FIREBASE_* variables.
  4. Under Service accounts → Generate new private key, download the JSON and extract project_id, client_email, and private_key into the server-only FIREBASE_* variables.
  5. Enable Analytics and link the GA4 property — required for the GA4 Measurement Protocol.

7.3 Stripe

  1. Get test API keys from Developers → API Keys.
  2. Local development webhook:
    stripe login
    stripe listen --forward-to localhost:3000/api/webhook
    Copy the whsec_ secret into STRIPE_WEBHOOK_SECRET.
  3. For production, register an endpoint at https://yourdomain.com/api/webhook and subscribe to:
    • checkout.session.completed
    • payment_intent.succeeded
    • charge.refunded

7.4 Gmail OAuth2 for email

  1. At Google Cloud Console enable the Gmail API for your project.
  2. Create an OAuth client ID (Web application).
  3. Authorize redirect URI https://developers.google.com/oauthplayground.
  4. Use the OAuth Playground with your own credentials to obtain a refresh token for the scope https://mail.google.com/.
  5. Paste the credentials into GOOGLE_* env vars.

7.5 GA4 Measurement Protocol

  1. In GA4 console open Admin → Data Streams → Web.
  2. Click Measurement Protocol API secrets → Create and copy the secret to GA4_API_SECRET.
  3. The same property's Measurement ID becomes GA4_MEASUREMENT_ID.
  4. Mark purchase, sign_up, and begin_checkout as conversion events for Monetisation reports.

08Running the App

Available scripts

ScriptCommandPurpose
devpnpm devWebpack-based dev server on :3000
dev:turbopnpm dev:turboTurbopack dev server (faster HMR)
buildpnpm buildProduction build (Next.js)
startpnpm startRun the built app
formatpnpm formatBiome format everything
lintpnpm lintBiome check (read-only)
lint:fixpnpm lint:fixBiome check with safe auto-fixes
typecheckpnpm typechecktsc --noEmit
cipnpm citypecheck + lint + build (CI parity)
typegenpnpm typegenRegenerate sanity.types.ts

Local URLs

  • http://localhost:3000 — Storefront
  • http://localhost:3000/studio — Sanity Studio
  • http://localhost:3000/admin — Admin Dashboard
  • http://localhost:3000/employee — Employee Portal
  • http://localhost:3000/vendor — Vendor Portal
  • http://localhost:3000/docs — This documentation

09Project Structure

GoFarm uses the Next.js App Router with route groups for isolation. Server actions live in actions/, shared helpers in lib/, schemas in sanity/.

gofarm/
├── app/                          # Next.js App Router
│   ├── (client)/                 # Public storefront route group
│   │   ├── (public)/             # About, FAQ, contact, etc.
│   │   ├── (user)/               # Cart, checkout, dashboard
│   │   ├── blog/  brands/  category/  collection/
│   │   ├── compare/ deal/ product/ products/ shop/
│   │   ├── orders/  vendor-info/  vendor-registration/
│   │   ├── home-2/  home-3/  home-4/
│   │   └── page.tsx              # Homepage
│   │
│   ├── (admin)/admin/            # Admin dashboard
│   ├── (auth)/                   # Sign-in / Sign-up
│   ├── (employee)/employee/      # Fulfilment portal
│   │
│   ├── api/                      # API routes
│   │   ├── auth/      checkout/   payment/   webhook/
│   │   ├── admin/     user/       vendor/    employee/
│   │   ├── orders/    coupons/    categories/
│   │   ├── menus/     newsletter/ contact/
│   │   ├── analytics/ addresses/  store-settings/
│   │   └── ...
│   │
│   ├── studio/                   # Embedded Sanity Studio
│   ├── docs/                     # This documentation page
│   ├── layout.tsx                # Root layout (Jost, providers)
│   ├── globals.css
│   ├── robots.ts
│   └── sitemap.ts
│
├── actions/                      # "use server" actions
├── components/                   # Shared UI components
│   ├── ui/                       # shadcn primitives
│   ├── admin/  vendor/  employee/
│   ├── cart/  checkout/  product/
│   └── AuthInitializer.tsx  AnalyticsProvider.tsx
│
├── hooks/                        # Client-side hooks
├── lib/                          # Framework-agnostic helpers
│   ├── firebase/admin.ts
│   ├── auth/server.ts
│   ├── analytics/server.ts
│   └── logger.ts
│
├── sanity/                       # CMS configuration
│   ├── schemaTypes/              # 25+ content schemas
│   ├── queries/                  # Centralised GROQ
│   └── helpers/  lib/  env.ts
│
├── stores/                       # Zustand state
├── store.ts                      # Legacy cart store
├── types/   config/   constants/
├── public/                       # Static assets (logo.svg, etc.)
├── scripts/                      # CLI scripts
├── biome.json                    # Format + lint config
├── lefthook.yml                  # Git hooks
├── commitlint.config.mjs
├── next.config.ts
├── sanity.config.ts
└── tsconfig.json

10Routing

The App Router uses parenthesised route groups to isolate layouts without changing URLs. Each group has its own layout.tsx and error.tsx.

Route groupPurposeAudienceAuth
(client)/(public)Marketing, FAQ, contact, termsAnonymousNone
(client)Shop, products, blog, brandsVisitorsNone
(client)/(user)Cart, checkout, dashboard, wishlistSigned-in customersrequireUser()
(auth)Sign in, sign up, forgot passwordAnyoneNone
(admin)Product / order / user managementAdmins onlyrequireRole("admin")
(employee)Fulfilment, deliveries, warehouseEmployeesrequireRole("employee")

Edge middleware

proxy.ts runs at the Edge for every request. It checks the __session cookie and redirects unauthenticated users away from /admin, /employee, /cart, /checkout, and /user. Role checks happen in the Node-runtime layout because firebase-admin is not available at the Edge.

11Authentication

Identity is owned entirely by Firebase Authentication. Sanity stores only the things Firebase does not — addresses, wallet, wishlist — keyed by the Firebase UID.

Session lifecycle

Browser                       /api/auth/session              Firebase Admin
   │                                  │                          │
   │ signInWithEmail / Google         │                          │
   │ ─────────────────────────────▶   │                          │
   │  idToken (1h TTL)                │ verifyIdToken            │
   │                                  │ ───────────────────────▶ │
   │                                  │ createSessionCookie(14d) │
   │ ◀───────────────────────────────                            │
   │  Set-Cookie: __session;          │                          │
   │  HttpOnly; Secure; SameSite=Lax  │                          │
   │                                  │ ensureSanityUser(uid)    │
   │                                  │ ◀─── idempotent ──────── │

Key files

  • lib/firebase/admin.ts — single Admin SDK init.
  • lib/auth/server.ts — canonical server auth helpers: requireUser(), requireRole(), currentUserIsAdmin().
  • app/api/auth/session/route.ts — POST creates session cookie, DELETE revokes refresh tokens.
  • stores/authStore.ts — Zustand store mirroring Firebase auth state to React.
  • components/AuthInitializer.tsx — subscribes toonIdTokenChanged and pushes ID tokens to /api/auth/session.

Server-side usage

// app/(client)/(user)/user/page.tsx
import { requireUser } from "@/lib/auth/server";

export default async function UserDashboard() {
  const user = await requireUser();
  return <Dashboard user={user} />;
}

12Authorization & Roles

Roles live in Firebase custom claims so they are present in the JWT and require no database round-trip on every request.

RoleClaimGrants
Admin{ admin: true }Full /admin access, role grants, store settings, analytics
Employee{ employee: true }/employee portal, order fulfilment, deliveries
Vendor{ vendor: true }/vendor dashboard, manage own products / payouts
Customer(no claim)Default — shop, checkout, user dashboard

Granting a role

# Preview (no changes)
pnpm tsx scripts/sync-claims.ts

# Commit
pnpm tsx scripts/sync-claims.ts --apply
After granting a claim, revokeRefreshTokens(uid)is called so the new claim is reflected on the user's next request.

13Sanity CMS

Sanity is the system of record for catalog, marketing pages, blog, and per-user domain data (orders, addresses, wallet). Schemas live in sanity/schemaTypes/.

SchemaPurposeKey fields
productCatalog itemtitle, slug, price, images, variants, category
productVariantSKU-level variantsize, color, weight, stock
categoryNested categoriestitle, slug, parent, image
brandBrand / farmer profilename, logo, story
orderCustomer orderfirebaseUid, products[], status, totalPrice
userProfile + walletfirebaseUid, addresses, wishlist, wallet
reviewProduct reviewproduct, rating, body, approved
couponDiscount codescode, type, value, expiry, usage
subscriptionNewsletter subscriberemail, source, optedInAt
vendorApplicationVendor onboardingfirebaseUid, businessName, status
walletWithdrawalPayout requestfirebaseUid, amount, status, bankInfo
storeSettingsGlobal store configcurrency, tax, shipping, branding
menu / bannerSite nav & herotitle, items[], link
blog / blogCategoryContent marketingtitle, slug, body (PortableText)

Queries

GROQ queries are never inlined in components. They live in sanity/queries/*.ts as typed functions.

// sanity/queries/userQueries.ts
export const ordersByUser = `
  *[_type == "order" && firebaseUid == $uid]
    | order(orderDate desc) {
      _id, status, totalPrice, currency,
      products[]{ quantity, product->{title, slug, image} }
    }
`;

Whenever a schema changes, run pnpm typegen to rebuild sanity.types.ts.

14API Reference

All routes live under app/api/**. Most mutations now prefer Server Actions in actions/; the API routes remain for webhooks and AJAX endpoints used by the dashboards.

EndpointMethodAuthPurpose
/api/auth/sessionPOST / DELETEPublic / cookieCreate or destroy session cookie
/api/auth/check-adminGETSessionReturns { isAdmin }
/api/auth/roleGETSessionReturns active role(s) from claims
/api/auth/sync-userPOSTSessionSync Firebase user into Sanity
/api/checkout/stripePOSTSessionCreate Stripe Checkout session
/api/webhookPOSTStripe sigProcess payment success, emit GA4 purchase
/api/user/profileGET / PATCHSessionRead or update profile
/api/user/cartGET / POST / DELETESessionPersistent cart
/api/user/ordersGETSessionList user orders
/api/user/wishlistGET / POST / DELETESessionManage wishlist
/api/user/addressesallSessionShipping addresses CRUD
/api/admin/ordersGET / PATCHAdmin claimList & manage orders
/api/admin/productsallAdmin claimCRUD products
/api/admin/usersGET / PATCHAdmin claimList + manage users
/api/admin/vendor-requestsGET / POSTAdmin claimApprove / reject vendors
/api/admin/analyticsGETAdmin claimAggregate KPIs
/api/vendor/*variousVendor claimVendor product / orders / withdrawal
/api/employee/*variousEmployee claimFulfilment endpoints
/api/coupons/validatePOSTSessionValidate coupon at checkout
/api/newsletterPOSTPublicSubscribe email
/api/contactPOSTPublicContact form
/api/categoriesGETPublicNavigation data

Server Actions

Mutations preferred over API routes — typed end-to-end. All actions return a discriminated union and never throw across the network boundary.

type ActionResult<T> =
  | { ok: true; data: T }
  | { ok: false; error: string };

"use server";
export async function createReview(
  input: ReviewInput
): Promise<ActionResult<Review>> {
  const user = await requireUser();
  // … validate with zod, write to Sanity, revalidate tags …
}

15State Management

Zustand is the only client store. Each concern has its own slice; stores subscribe to authStore when they need to react to sign-in / sign-out.

StorePathState
authStorestores/authStore.tscurrentUser, loading, role
cartStorestore.tsitems, totals, hydrate / flush
cartAddedModalStorestores/cartAddedModalStore.tsopen/close added-to-cart modal
compareStorestores/compareStore.tsproduct compare list
shareStorestores/shareStore.tsshare sidebar visibility + payload
userDataStorestores/userDataStore.tsprofile, wallet, points cache

16Payments & Orders

Checkout flow

Cart ──▶ /checkout ──▶ /api/checkout/stripe ──▶ Stripe Checkout
                              │
                              ▼
                       Sanity order doc (status: pending)
                              │
                              ▼
                Stripe ──▶ /api/webhook (signature verified)
                              │
            ┌─────────────────┼──────────────────────┐
            ▼                 ▼                      ▼
    update order        send confirmation     GA4 purchase
    status: paid            email             (Measurement Protocol)

Order status machine

  1. pending — created, awaiting payment.
  2. paid — Stripe / SSLCommerz confirmed.
  3. processing — assigned to employee.
  4. shipped — courier tracking attached.
  5. delivered — final.
  6. cancelled — refund issued if paid.
Webhook timeouts and analytics failures are caught and logged. Analytics never blocks payment processing.

17Analytics (GA4)

GoFarm emits the full GA4 e-commerce funnel so Firebase Console → Analytics → Realtime, Monetisation, and Retention reports auto-populate.

Funnel stageGA4 eventFires from
Browseview_item_listCategory & home pages
Detailview_itemProduct page
SearchsearchHeader search bar
Cartadd_to_cart / remove_from_cartAddToCart / QuantityButtons
Cartview_cartCart page mount
Checkoutbegin_checkout / add_payment_infoCheckout steps
Orderpurchase / refundStripe webhook (server)
Authlogin / sign_up / logoutAnalyticsProvider

components/AnalyticsProvider.tsx calls setUserId(uid) and setUserProperties() whenever auth state changes, enabling cross-device cohort reports. Append ?debug=1 to any page to fire events with debug_mode: true so they appear in GA4 DebugView.

18Admin Dashboard

The admin dashboard lives at /admin behind the admin custom claim.

Catalog

  • /admin/products — list, edit, delete
  • Bulk update prices / stock
  • Variant management

Orders

  • /admin/orders — full order list
  • Status changes & assignment
  • Refund initiation

Users & vendors

  • /admin/users — search, roles, suspend
  • /admin/vendor-requests — approve / reject
  • Wallet adjustments

Content

  • /admin/reviews — moderation
  • /admin/subscriptions — newsletter
  • /admin/notifications

Operations

  • /admin/employees — manage staff
  • /admin/stores — branding & settings

Analytics

  • Revenue, AOV, conversion rate
  • Top products and categories
  • Cohort retention

19Vendor & Employee Portals

Vendor Portal — /vendor

  • Sign-up at /vendor-registration, awaits admin approval.
  • Once approved, the vendor custom claim is set and the vendor sees their dashboard.
  • Manage own products, view orders, request payouts via walletWithdrawal.

Employee Portal — /employee

  • Granted manually by an admin via the user management UI.
  • Order queue, status transitions, delivery confirmations, warehouse stock movements.
  • Activity is logged to the order's history array for audit.

20Coding Standards

Standards are enforced by tooling rather than convention. Biome formats and lints on every commit; commitlint validates every commit message; TypeScript strict mode catches type errors before they ship.

ConcernToolWhere it runs
Format + lintBiome v2Pre-commit (staged), CI (full repo)
Type checktsc --noEmitPre-push, CI
HookslefthookAuto-installed on pnpm install
Commit messagescommitlint + Conventional Commitscommit-msg hook
Editor consistency.editorconfigEvery editor
CIGitHub ActionsEvery PR + push to main

Naming conventions

ItemConventionExample
React componentsPascalCase.tsxProductCard.tsx
Hooksuse-kebab-case.tsuse-cart.ts
Server actionskebab-case.tscreate-order.ts
Storeskebab-case-store.tscart-store.ts
Booleansis/has/can/shouldisLoading
ConstantsSCREAMING_SNAKE_CASEMAX_CART_ITEMS
Sanity schema namecamelCase, singularwalletWithdrawal

21Git Workflow

Conventional Commits

<type>(<scope>): <subject>

# Allowed types
feat, fix, docs, style, refactor, perf,
test, build, ci, chore, revert

# Examples
feat(cart): add coupon stacking
fix(checkout): correct VAT rounding
chore(deps): bump biome to 2.4.16

Pre-commit hooks (lefthook)

HookRunsWhy
pre-commitbiome check --writeAuto-format & safe lint fixes
pre-commitforbid-secretsReject .env* (except example)
commit-msgcommitlint --editEnforce Conventional Commits
pre-pushtsc --noEmitFull project typecheck
pre-pushbiome ci .Full-repo lint & format check
Never use --no-verify to bypass hooks. If a hook fails, investigate.

22Deployment

Deploy to Vercel (recommended)

  1. Push your branch to GitHub.
  2. At vercel.com, import the repository.
  3. Framework Preset: Next.js. Build command: pnpm build.
  4. Add every variable from .env.local in Project Settings → Environment Variables.
  5. After the first deploy, update NEXT_PUBLIC_BASE_URL to your domain.
  6. In Sanity → API → CORS origins, add the production URL with credentials enabled.
  7. In Stripe, create a production webhook pointing to /api/webhook and paste the new whsec_ into Vercel env.
  8. In Firebase → Authentication → Authorized domains, add the production domain.

Post-deploy checklist

  • Sign in with the email listed in ADMIN_EMAILS — the admin custom claim is set automatically on first login.
  • Run the claims backfill: pnpm tsx scripts/sync-claims.ts --apply.
  • In GA4, mark purchase, sign_up, begin_checkout as conversion events.
  • Place a test order with Stripe's test card 4242 4242 4242 4242.
  • Confirm the GA4 Realtime view shows your purchase event within 30 seconds.

23Pricing & Hire Me

Want me to set up GoFarm for you instead of doing it yourself? Every package starts from the same installation base of $100 — the additional tiers simply layer add-ons on top. Honest, freelance-market rates from Bangladesh, all in USD. Each package is a fixed scope, fixed price. Hourly is available for ad-hoc changes after handover.

Starter

Installation Only

Delivery: 2–3 business days

$100base / one-time
Installation base
  • Clone & install the project on your machine or VPS
  • Configure Firebase, Sanity, Stripe, Gmail OAuth2
  • Wire up all environment variables
  • Create the first admin account
  • End-to-end smoke test: sign up → checkout → order
  • Vercel production deploy
  • 1 video / written handover walkthrough
  • 3-day post-handover bug fix window
Get this package →
Most popularStandard

Install + Branding

Delivery: 3–5 business days

$100 + $50= $150 total
Installation basebranding add-on
  • Everything in the Starter package
  • Replace logo, favicon, and OG image
  • Apply your brand colors via Tailwind tokens
  • Update site name, footer, contact info
  • Seed initial product categories (up to 10)
  • Configure SSLCommerz (optional, BD market)
  • GA4 + DebugView verification
  • 7-day post-handover bug fix window
Get this package →
Premium

Install + Customization

Delivery: 5–7 business days

$100 + $100= $200 total
Installation basecustomization add-on
  • Everything in the Standard package
  • Up to 3 hours of custom development
  • 1 extra page or layout variant
  • 1 small feature tweak (e.g. new product field, banner)
  • Connect a custom domain + SSL on Vercel
  • Email template customization
  • Performance pass (Lighthouse mobile ≥ 90)
  • 14-day post-handover support
Get this package →

Hourly & ongoing work

Type of workRate (USD)Notes
Bug fix / small change$20 / hourMinimum 1 hour. Examples: text change, color tweak, link fix.
Custom feature / integration$25 / hourNew API integration, custom page, dashboard widget.
Complex feature / refactor$30 / hourMulti-page flows, payment provider, data migration.
Performance / SEO audit$80 (flat)Lighthouse + Core Web Vitals report with actionable fixes.
Monthly retainer$300 / monthUp to 15 hours/month. Priority response within 24h.
How to book. Email reactjsbd@gmail.comwith the package name and a short description of what you need. I'll reply within 24 hours with a Stripe / Wise / PayPal invoice. 50% upfront, 50% on handover for fixed packages.

What's not included

  • Third-party service costs (Vercel Pro, Sanity paid plan, Google Workspace, etc.) — you pay these directly to the providers.
  • Stripe / SSLCommerz business verification — done by you on their dashboards.
  • Domain & SSL purchase — you buy from your preferred registrar; I configure the DNS.
  • Content creation (product photos, descriptions, blog posts).
Ready to launch?Let's get GoFarm live this week.Email me with your package choice and timeline.
Hire me →

24Troubleshooting

SymptomLikely causeFix
"Already exists" Firebase Admin warningApp initialised more than onceImport only from lib/firebase/admin.ts.
Sanity Studio is blank at /studioTypes out of syncpnpm typegen, then restart dev server.
Stripe webhook rejectedRaw body missing or wrong signatureVerify STRIPE_WEBHOOK_SECRET matches the endpoint.
Sign-in works but admin redirects to /admin claim missingAdd email to ADMIN_EMAILS or run sync-claims.ts --apply.
Env var changes have no effectDev server not restartedRestart with pnpm dev. Vercel needs a redeploy.
Builds OOM on small machinesWebpack memory budgetUse Turbopack: pnpm dev:turbo, or set NODE_OPTIONS=--max-old-space-size=4096.
pnpm installIgnored build scripts (pnpm v10)Allowlisted in pnpm.onlyBuiltDependencies. Run install again.
lefthook hooks not firingSkipped installpnpm exec lefthook install
GA4 Realtime shows nothingWrong Measurement ID or missing API secretVerify GA4_MEASUREMENT_ID + GA4_API_SECRET.

25Support

License. GoFarm is MIT-licensed. Everything in the repository is included — there are no locked features. Buyers of any pricing package get the same codebase, the same docs, and the same support channels.

Maintainer

Noor Mohammad

Full-Stack Developer & Instructor

reactjsbd@gmail.com

Project

GoFarm

Modern agricultural e-commerce platform

Live demo: gofarm.reactbd.com

You made it to the end!

That's every page, table, and config flag in GoFarm — nicely done. Now go build something delicious. 🥕🍅🥦

Crafted withbyNoor Mohammadv1.0
Buy Production Code