v2.0.0 is out — finance module, support tickets, push notifications.Read changelog
PropertyPro
DocsDocumentation
⌘ K
Documentation·Setup & installation

Setup & Installation

Everything you need to install, configure, and deploy PropertyPro — from your first pnpm install to a custom domain on production.

Chapter 01 · Overview

Welcome to PropertyPro

PropertyPro is a complete property management application built with Next.js 16, React 19, and MongoDB. This documentation covers everything from your first install to deploying in production.

What's in the package

Full source code, database schema, seed data, and a self-contained PWA-ready Next.js app.

License

One regular license per end product. Lifetime updates within the same major version.

Stack

Next.js 16, React 19 + Compiler, TypeScript, Tailwind CSS v4, MongoDB, Stripe.

Support

6 months of buyer support included. Renewable from your CodeCanyon account.

Looking for end-user docs?

If you're configuring tenants, leases, and day-to-day workflows, head to the User Manual instead.

Chapter 02 · Quickstart

Get running in 5 minutes

If you're already comfortable with Node, pnpm, and MongoDB, this is the express path. Each step is expanded later in the docs.

  1. 1

    Install dependencies

    From the unzipped folder, install all packages with pnpm.

    bash
    cd propertypro
    pnpm install
  2. 2

    Copy env file

    Duplicate the example env and fill in your database, Stripe, and SMTP credentials.

    bash
    cp .env.example .env.local
  3. 3

    Connect MongoDB & seed

    Set MONGODB_URI, then load demo data so you can log in immediately.

    bash
    pnpm db:seed
  4. 4

    Start the dev server

    Open http://localhost:3000 — the demo admin is admin@propertypro.app / admin1234.

    bash
    pnpm dev

Chapter 03 · Requirements

System & runtime requirements

PropertyPro runs anywhere Node.js does. These versions are tested in CI — older versions may work but aren't supported.

Node.js 20.11+

Use 20 LTS or 22. We do not support Node 18 due to React Compiler dependencies.

pnpm 9+

Required. Install with corepack enable && corepack prepare pnpm@latest --activate.

MongoDB 6+

MongoDB Atlas is recommended. Self-hosted MongoDB works when MONGODB_URI points to your server.

Object storage

Cloudflare R2 stores property photos, tenant documents, and uploaded files.

Hosting suggestion

For most buyers, Vercel + MongoDB Atlas is the fastest path. The full deploy guide covers VPS and Docker too.

Chapter 04 · Download & Setup

Get the source running locally

Download from CodeCanyon, unzip, and install. PropertyPro ships as a ready-to-run Next.js project — no build steps required to start dev.

  1. 1

    Download from CodeCanyon

    Sign in to CodeCanyon → Downloads → PropertyPro. Choose 'All files & documentation'.

  2. 2

    Unzip the package

    Extract the archive to a permanent location. The main folder is /propertypro.

    bash
    unzip propertypro-v2.0.0.zip -d ~/projects/
    cd ~/projects/propertypro
  3. 3

    Install dependencies

    We use pnpm for fast, deterministic installs. Run this once after every download or update.

    bash
    pnpm install
  4. 4

    Verify the install

    A quick smoke test confirms everything resolved correctly.

    bash
    pnpm typecheck
    pnpm lint

Don't use npm or yarn

The lockfile is pnpm-only. Mixing package managers will corrupt resolutions — stick to pnpm.

Chapter 05 · Environment Variables

Configure .env.local

All secrets live in .env.local. The included .env.example documents every key. Below is a complete MongoDB-ready example.

.env.local
bash
# Database Configuration (MongoDB Atlas)
MONGODB_URI=mongodb+srv://username:password@cluster0.kbnje.mongodb.net/propertypro

# Self-Hosted MongoDB
# MONGODB_URI=mongodb://mongo:password@your_ip_address:27017/propertypro
# MONGODB_DB=propertypro

# NextAuth Configuration
NEXTAUTH_URL=http://localhost:3000
NEXTAUTH_SECRET=your-nextauth-secret
AUTH_TRUST_HOST=true
AUTH_URL=http://localhost:3000

# Cloudflare R2 (Replace with your actual keys from https://dash.cloudflare.com)
R2_ACCOUNT_ID=your-r2-account-id
R2_ACCESS_KEY_ID=your-r2-access-key-id
R2_SECRET_ACCESS_KEY=your-r2-secret-access-key
R2_BUCKET_NAME=your-r2-bucket-name
R2_PUBLIC_URL=https://your-custom-domain.com
NEXT_PUBLIC_R2_PUBLIC_URL=https://your-custom-domain.com

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

# Email (SMTP)
EMAIL_SERVER_HOST=smtp.gmail.com
EMAIL_SERVER_PORT=587
EMAIL_SERVER_USER=your-email@gmail.com
EMAIL_SERVER_PASSWORD=your-email-password
EMAIL_FROM=your-email@gmail.com

# File Upload Configuration
UPLOAD_MAX_SIZE=10485760
UPLOAD_ALLOWED_TYPES=image/jpeg,image/png,image/webp,application/pdf

# Application Configuration (optional)
APP_NAME=propertypro
APP_URL=http://localhost:3000
SUPPORT_EMAIL=support@propertypro.com

# Web Push (VAPID)
NEXT_PUBLIC_VAPID_PUBLIC_KEY=your-vapid-public-key
VAPID_PRIVATE_KEY=...
VAPID_SUBJECT=mailto:admin@propertypro.app
KeyRequiredDescription
MONGODB_URIRequiredMongoDB Atlas or self-hosted MongoDB connection string for the PropertyPro database.
MONGODB_DBOptionalDatabase name override. Useful when your connection string does not include /propertypro.
NEXTAUTH_SECRETRequiredRandom secret used to sign auth sessions. Never commit this.
NEXTAUTH_URL / AUTH_URLRequiredPublic URL of your deployment, used in emails, callbacks, and auth redirects.
R2_ACCOUNT_IDRequiredCloudflare account ID used to build the R2 S3 endpoint.
R2_ACCESS_KEY_IDRequiredAccess Key ID from a Cloudflare R2 API token with object read/write access.
R2_SECRET_ACCESS_KEYRequiredSecret Access Key for the same R2 API token. Store it once; Cloudflare does not show it again.
R2_BUCKET_NAMERequiredName of the bucket that stores uploaded property photos and documents.
R2_PUBLIC_URL / NEXT_PUBLIC_R2_PUBLIC_URLRequiredPublic origin for reading uploaded files, either a production custom domain or a development r2.dev URL.
STRIPE_SECRET_KEYRequiredServer-side Stripe key. Use test keys in development.
STRIPE_WEBHOOK_SECRETRequiredSigning secret for the /api/webhooks/stripe endpoint.
EMAIL_SERVER_*RequiredOutbound email credentials for invites, receipts, and reminders.
VAPID_*OptionalRequired only if you want web push notifications. Generate with npx web-push generate-vapid-keys.
UPLOAD_*OptionalUpload size and MIME type limits for images, WebP files, and PDFs.

Generate NEXTAUTH_SECRET fast

Run openssl rand -base64 32 in your terminal and paste the output as the value.

Chapter 06 · Database Setup

Connect MongoDB & seed data

PropertyPro stores application data in MongoDB. Create a MongoDB Atlas cluster or self-hosted database, then point MONGODB_URI at it before starting the app.

  1. 1

    Create a MongoDB database

    Create a MongoDB Atlas cluster and database named propertypro, or prepare a self-hosted MongoDB instance.

    bash
    # MongoDB Atlas example
    MONGODB_URI=mongodb+srv://username:password@cluster0.kbnje.mongodb.net/propertypro
  2. 2

    Allow network access

    In MongoDB Atlas, add your local IP address for development and your hosting provider's outbound IPs for production.

    txt
    Atlas → Network Access → Add IP Address
  3. 3

    Seed demo data (optional)

    Loads two demo properties, ten units, three tenants, and an admin account so you can explore immediately.

    bash
    pnpm db:seed
  4. 4

    Inspect with MongoDB Compass

    Use MongoDB Compass or the Atlas Data Explorer to browse collections and verify seeded records.

    txt
    mongodb+srv://username:password@cluster0.kbnje.mongodb.net/propertypro

Production: skip the seed

Never run pnpm db:seed against a live database — it inserts demo records and accounts intended for evaluation.

Chapter 07 · Running Locally

Start the dev server

Two scripts cover 99% of dev work: dev and build. The PWA service worker is disabled in dev to keep iteration fast.

  1. 1

    Start in development

    Hot-reload, fast refresh, and source maps. Defaults to port 3000.

    bash
    pnpm dev
  2. 2

    Run a production build

    Compiles, treeshakes, and runs Next.js production server. Use this to validate before deploying.

    bash
    pnpm build
    pnpm start
  3. 3

    Sign in with the demo admin

    If you ran the seed, an admin account exists out of the box.

    txt
    Email:    admin@propertypro.app
    Password: admin1234

Change the demo password

First action in production: log in, open Settings → Profile, and rotate the seeded password.

Chapter 08 · Cloudflare R2

Configure file storage with Cloudflare R2

PropertyPro uses Cloudflare R2 for property images, tenant documents, and other uploaded files. Configure one private write path through R2 API credentials and one public read URL for displaying saved files.

  1. 1

    Create an R2 bucket

    In Cloudflare, open Storage & databases -> R2 and create a bucket for PropertyPro uploads. Use a lowercase bucket name with numbers and hyphens only, then place that exact bucket name in R2_BUCKET_NAME.

    bash
    R2_BUCKET_NAME=your-r2-bucket-name
  2. 2

    Create a scoped R2 API token

    From the R2 overview, open Manage API Tokens, create an API token with Object Read & Write permission, and scope it to the PropertyPro bucket. Copy the Access Key ID, Secret Access Key, and account ID before leaving the confirmation screen.

    bash
    R2_ACCOUNT_ID=your-r2-account-id
    R2_ACCESS_KEY_ID=your-r2-access-key-id
    R2_SECRET_ACCESS_KEY=your-r2-secret-access-key
    R2_BUCKET_NAME=your-r2-bucket-name
  3. 3

    Enable public file delivery

    For production, connect a custom domain such as assets.yourdomain.com to the bucket. For local testing only, you may enable the Cloudflare-managed r2.dev public development URL. Set both public URL variables to the exact origin with no trailing slash.

    bash
    # Production custom domain
    R2_PUBLIC_URL=https://your-custom-domain.com
    NEXT_PUBLIC_R2_PUBLIC_URL=https://your-custom-domain.com
    
    # Local or staging with R2 public development URL
    # R2_PUBLIC_URL=https://pub-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.r2.dev
    # NEXT_PUBLIC_R2_PUBLIC_URL=https://pub-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.r2.dev
  4. 4

    Allow the image host in Next.js

    The bundled next.config.ts already allows r2.dev and r2.cloudflarestorage.com image hosts. If you use a custom R2 domain and render uploaded images through next/image, add that hostname to images.remotePatterns, then rebuild.

    next.config.ts
    ts
    images: {
      remotePatterns: [
        {
          protocol: "https",
          hostname: "assets.yourdomain.com",
          port: "",
          pathname: "/**",
          search: "",
        },
      ],
    }
  5. 5

    Verify uploads

    Restart the app after changing environment variables, upload a property image or tenant document, then open the saved file URL. If the upload succeeds but previews fail, check the public bucket URL and image remote pattern first.

R2 S3 endpoint format
txt
https://<ACCOUNT_ID>.r2.cloudflarestorage.com

Keep write credentials server-only

Never expose R2_ACCESS_KEY_ID or R2_SECRET_ACCESS_KEY in NEXT_PUBLIC_* variables. Only NEXT_PUBLIC_R2_PUBLIC_URL should be readable by the browser.

Use custom domains in production

Cloudflare's r2.dev public development URLs are intended for non-production traffic. A custom domain gives you normal Cloudflare cache, access control, WAF, and bot-management options.

Chapter 09 · Stripe Payments

Accept rent payments online

PropertyPro uses Stripe Checkout for one-time invoices and Stripe Customer Portal for tenant self-service. Both work with test keys out of the box.

  1. 1

    Get your API keys

    Stripe Dashboard → Developers → API keys. Copy the secret and publishable keys into .env.local.

  2. 2

    Create a webhook endpoint

    Point Stripe at /api/webhooks/stripe on your deployed URL. Subscribe to checkout.session.completed and invoice.payment_succeeded.

    bash
    # Webhook URL
    https://yourdomain.com/api/webhooks/stripe
  3. 3

    Test webhooks locally

    Use the Stripe CLI to forward events to your dev server while developing.

    bash
    stripe listen --forward-to localhost:3000/api/webhooks/stripe
  4. 4

    Switch to live mode

    When ready, swap test keys (sk_test_*, pk_test_*) for live keys (sk_live_*, pk_live_*) and re-create the webhook in live mode.

Chapter 10 · Email / SMTP

Wire up transactional email

Lease reminders, payment receipts, password resets, and tenant invites all go through one SMTP transport. We've tested Resend, SendGrid, Postmark, and standard SMTP servers.

Resend (recommended)

Easiest for new buyers. Free tier covers most small portfolios. EMAIL_SERVER_HOST=smtp.resend.com, EMAIL_SERVER_USER=resend.

SendGrid

Higher limits and better deliverability for large portfolios. EMAIL_SERVER_HOST=smtp.sendgrid.net.

Postmark

Best for transactional-only email. EMAIL_SERVER_HOST=smtp.postmarkapp.com.

Gmail / generic SMTP

Works for testing but rate-limited. Not recommended for production.

Verify your sender domain

Always set up SPF, DKIM, and DMARC for EMAIL_FROM's domain — without it, emails land in spam.

Chapter 11 · Push Notifications

Enable web push

Push notifications use the Web Push API with VAPID keys. Tenants and admins get instant alerts for payments, requests, and chats.

  1. 1

    Generate VAPID keys

    Run the bundled generator. Copy both keys into .env.local.

    bash
    pnpm gen:vapid
  2. 2

    Set NEXT_PUBLIC_VAPID_PUBLIC_KEY

    The client uses this public key to subscribe browsers to the push service.

  3. 3

    Set VAPID_PRIVATE_KEY

    The server uses this to sign push payloads. Never expose it to the browser.

  4. 4

    Test from the dashboard

    Sign in, allow notifications when prompted, then go to Settings → Notifications → Send test.

Chapter 12 · Branding & Theme

Make it yours

All brand assets live under /public and the color palette is defined as Tailwind CSS variables. No code changes required for a basic rebrand.

  1. 1

    Replace the logo

    Drop your SVG logo at /public/logo.svg. The dashboard reads from this path automatically.

  2. 2

    Update the favicon & PWA icons

    Replace /public/favicon.ico and the icons under /public/icons/ (sizes 192, 256, 384, 512).

  3. 3

    Tweak brand colors

    Edit the --brand-* tokens in app/globals.css. Tailwind picks them up across the app.

    app/globals.css
    css
    :root {
      --brand-50:  oklch(0.97 0.02 230);
      --brand-500: oklch(0.62 0.18 230);
      --brand-700: oklch(0.45 0.18 230);
    }
  4. 4

    Update site metadata

    Edit app/layout.tsx to change the default title, description, and OG image.

Chapter 13 · Multi-language

Add or edit languages

PropertyPro ships with English, Arabic, French, Spanish, and Bengali. Locales live as JSON files under /messages and are loaded with next-intl.

  1. 1

    Edit existing strings

    Open /messages/<locale>.json and edit values directly. Changes hot-reload in dev.

  2. 2

    Add a new language

    Copy /messages/en.json to /messages/<your-locale>.json and translate values. Then register it in lib/i18n.ts.

    lib/i18n.ts
    ts
    export const locales = ["en", "ar", "fr", "es", "bn", "de"] as const;
    export const defaultLocale = "en";
  3. 3

    RTL support

    Arabic is enabled by default and switches the layout direction automatically. Add other RTL locales in lib/i18n.ts → rtlLocales.

Chapter 14 · Deploy to Vercel

One-click deploy (recommended)

Vercel is the fastest path to production. The whole flow takes under 10 minutes once your environment variables are ready.

  1. 1

    Push to a GitHub repo

    Create a private GitHub repo and push the source. Vercel will pull from it.

    bash
    git init
    git add .
    git commit -m "Initial PropertyPro setup"
    git remote add origin git@github.com:you/propertypro.git
    git push -u origin main
  2. 2

    Import the repo into Vercel

    vercel.com → New Project → Import. Vercel auto-detects Next.js — no build config needed.

  3. 3

    Add environment variables

    Project Settings → Environment Variables. Paste every key from your .env.local. Set APP_URL, NEXTAUTH_URL, and AUTH_URL to your Vercel URL.

  4. 4

    Connect MongoDB Atlas

    Add Vercel's outbound access to MongoDB Atlas Network Access, then set MONGODB_URI in Vercel before deploying.

    bash
    MONGODB_URI=mongodb+srv://username:password@cluster0.kbnje.mongodb.net/propertypro
  5. 5

    Add your custom domain

    Project Settings → Domains. SSL is provisioned automatically.

Chapter 15 · Deploy to VPS / Docker

Self-host on your own server

If you'd rather run on a VPS, PropertyPro ships with a production-ready Dockerfile and a sample docker-compose.yml that can run MongoDB alongside the app.

  1. 1

    Build & start the stack

    From the project root, build the images and run them in the background.

    bash
    docker compose up -d --build
  2. 2

    Seed demo data inside the container

    Load demo records only when you are setting up a test or evaluation instance.

    bash
    docker compose exec app pnpm db:seed
  3. 3

    Front with nginx + SSL

    Use nginx (or Caddy) to terminate TLS and proxy to localhost:3000. Caddy will provision Let's Encrypt automatically.

    Caddyfile
    nginx
    propertypro.yourdomain.com {
      reverse_proxy localhost:3000
    }
docker-compose.yml
yaml
services:
  app:
    build: .
    ports: ["3000:3000"]
    env_file: .env.local
    environment:
      MONGODB_URI: mongodb://propertypro:change-me@mongo:27017/propertypro?authSource=admin
    depends_on: [mongo]
  mongo:
    image: mongo:7
    restart: unless-stopped
    environment:
      MONGO_INITDB_ROOT_USERNAME: propertypro
      MONGO_INITDB_ROOT_PASSWORD: change-me
    volumes:
      - mongodata:/data/db
    ports: ["27017:27017"]

volumes:
  mongodata:

Use a managed database

Self-hosting MongoDB works but you'll own backups, replication, and upgrades. MongoDB Atlas offloads that work.

Chapter 16 · Custom Domain & SSL

Point your domain at PropertyPro

Once your app is live, route a custom domain to it. Both Vercel and Caddy provision SSL certificates for free.

  1. 1

    Add an A or CNAME record

    For Vercel, add a CNAME pointing to cname.vercel-dns.com. For your VPS, point an A record at the server IP.

  2. 2

    Verify in Vercel / Caddy

    Vercel auto-verifies once DNS propagates. Caddy reissues the certificate on the next request.

  3. 3

    Update application URLs

    Switch APP_URL, NEXTAUTH_URL, and AUTH_URL to https://yourdomain.com and redeploy. These are used in emails and auth callbacks.

Chapter 17 · Admin & Roles

Set up your team

After your first deploy, lock down the demo admin and create real users with scoped permissions.

  1. 1

    Sign in & rotate the demo password

    Log in as admin@propertypro.app, open Settings → Profile, and set a strong password.

  2. 2

    Invite your team

    Settings → Team → Invite. Each invitee gets an email with a one-time setup link.

  3. 3

    Assign roles

    Built-in roles: Admin, Manager, Accountant, Inspector, Tenant. Create custom roles under Settings → Roles.

  4. 4

    Audit log

    Every sensitive action is recorded. Review under Settings → Activity.

Don't share admin accounts

Shared logins break audit trails. Always invite a new user — even for short-term contractors.

Chapter 18 · Updates & Backups

Stay current and recoverable

PropertyPro ships minor updates monthly. Every release is non-destructive — your data and customizations stay intact.

  1. 1

    Download the latest build

    From your CodeCanyon downloads. Compare the version against the Changelog to plan the update.

  2. 2

    Diff and merge

    Use git or your favorite diff tool to merge the new files. Your /messages and /public assets are safe to keep as-is.

  3. 3

    Install and rebuild

    Install dependencies and run a production build after merging each release.

    bash
    pnpm install
    pnpm build
  4. 4

    Schedule database backups

    Use MongoDB Atlas automated backups or set up nightly mongodump on a VPS.

    bash
    # Cron: nightly backup at 02:00
    0 2 * * * mongodump --uri="$MONGODB_URI" --archive=/backups/propertypro-$(date +\%F).archive --gzip

Chapter 19 · Troubleshooting

Fix common issues

Most install problems fall into the same handful of buckets. Walk through these before opening a support ticket.

MONGODB_URI connection refused

Check the username, password, database name, and Atlas Network Access allowlist. For self-hosted MongoDB, confirm the authSource value.

Stripe webhook signature invalid

Make sure STRIPE_WEBHOOK_SECRET matches the secret of the specific endpoint, not your account secret.

Emails landing in spam

Set up SPF, DKIM, and DMARC for your sender domain. Resend & SendGrid have step-by-step UIs for this.

Push notifications not arriving

iOS Safari requires the PWA to be installed via Add to Home Screen first. Web push is unavailable in Incognito mode.

pnpm install fails

Delete node_modules and pnpm-lock.yaml, run corepack enable, then pnpm install fresh.

File uploads silently fail

Check R2_* variables, NEXT_PUBLIC_R2_PUBLIC_URL, upload limits, and whether your Cloudflare R2 bucket allows public reads from the configured URL.

Updates·Last updated May 2, 2026
↑ Back to top