Landing Page

Landing Page

Overview

URL: https://getdrop.no
Purpose: Multi-language marketing landing page for Drop — fintech payment app
Target users: All residents in Norway/Scandinavia (not diaspora-only)

Architecture

File Structure

landing/
├── index.html              # Main entry point (Norwegian default)
├── locales/                # 12 language JSON files (nb, en, sv, da, fi, bs, sr, hr, de, tr, sq, pl)
├── functions/
│   └── api/waitlist.js     # CF Function — waitlist signup endpoint
├── _headers                # Security headers (CSP, HSTS, X-Frame-Options)
├── wrangler.toml           # CF Pages + D1 config
├── package.json            # Dependencies (wrangler only)
├── manifest.json           # PWA manifest
├── sw.js                   # Service worker
├── favicon.svg             # Drop logo favicon
└── pages/                  # Static sub-pages (send-penger, qr-betaling, priser, etc.)

Hero Design Decision (2026-04-22)

Problem: CEO feedback — landing page showed fake app demo mockup (SpareBank balance, fake transactions, "Mama Jasmina") instead of actual product information.

Solution: Replaced demo mockup with info-first corridor card showing:

Code change: Commit dfa0b3b3 on main
MC task: #8729
Files changed: landing/index.html (155 insertions, 110 deletions)

Visual proof:

Verification:

curl https://getdrop.no | grep -c 'ps-balance'           # 0 (removed)
curl https://getdrop.no | grep -c 'phone-screen'         # 0 (removed)
curl https://getdrop.no | grep -c 'SpareBank'            # 0 (removed)
curl https://getdrop.no | grep -c 'Mama Jasmina'         # 0 (removed)
curl https://getdrop.no | grep -c 'corridor-card'        # 3 (present)

Waitlist Flow

  1. User submits email via form at #cta section
  2. POST /api/waitlist → CF Function at functions/api/waitlist.js
  3. Validation: Email regex + honeypot field (website)
  4. Storage: CF D1 database (drop-waitlist, binding DB)
  5. Schema: waitlist_signups table (id, email, source, created_at)
  6. Response: JSON {ok: true, message: 'Registrert!'}

Admin access: GET /api/waitlist?key=<WAITLIST_ADMIN_KEY> returns all signups (rate-limited, 5 attempts per 15 min)

Internationalization (i18n)

Languages: 12 supported

CodeLanguageFile
nbNorsk (bokmål)locales/no.json
enEnglishlocales/en.json
svSvenskalocales/sv.json
daDansklocales/da.json
fiSuomilocales/fi.json
bsBosanskilocales/bs.json
srSrpskilocales/sr.json
hrHrvatskilocales/hr.json
deDeutschlocales/de.json
trTürkçelocales/tr.json
sqShqiplocales/sq.json
plPolskilocales/pl.json

Implementation: Language switcher dropdown in nav, preference stored in localStorage

Deployment

Method: GitHub Actions workflow (.github/workflows/landing-deploy.yml)

Trigger: Push to main with changes in landing/** path

Process:

  1. Checkout repo
  2. Setup Node.js 20
  3. Install dependencies (npm ci)
  4. Deploy via Wrangler: wrangler pages deploy . --project-name=$CF_LANDING_PROJECT_NAME --branch=main

Secrets required:

DNS:

Security Headers

File: _headers

X-Content-Type-Options: nosniff
X-Frame-Options: DENY
Referrer-Policy: strict-origin-when-cross-origin
Permissions-Policy: camera=(), microphone=(), geolocation=()
X-XSS-Protection: 1; mode=block

Key Metrics

Future Improvements


Revision #2
Created 2026-04-22 21:54:40 UTC by John
Updated 2026-05-24 20:03:09 UTC by John