A premium, dark-themed luxury car rental website — multi-language (EN/FR/AR), Google Sheets-powered CMS, WhatsApp-driven bookings, built with Next.js, TypeScript, Tailwind CSS, and Framer Motion.
Live Demo — Try it live
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
- Dark editorial design — near-black background, gold accent, Fraunces display font
- Multi-language — English, French, Arabic with full RTL layout mirroring
- Google Sheets CMS — all data (cars, locations, testimonials, settings) from a published sheet
- WhatsApp bookings — no backend needed; all form submits open
wa.mewith a preformatted message - SEO optimized —
generateMetadata, JSON-LD schema (Product + LocalBusiness), sitemap.xml, robots.txt - Framer Motion animations — scroll-triggered reveals, parallax hero, hover effects
- Mobile-first — 375px viewport design, slide-in nav drawer, 44px+ tap targets
- Accessibility — heading hierarchy, focus states, aria-labels, AA color contrast
The site pulls all its content from a Google Sheet. No backend or database required.
Create a Google Sheet with these tabs (use the exact names):
Cars | Locations | Testimonials | WhyUs | Settings
Cars tab (Row 1 headers):
| id | slug | brand | model | year | category | transmission | fuelType | seats | doors | pricePerDay | pricePerWeek | pricePerMonth | deposit | description | features | images | status |
featuresandimagesare JSON arrays:["AC","GPS","Bluetooth"]status:available,booked,maintenance,retiredcategory:luxury-sedan,sports-car,luxury-suv,exotic,grand-tourer
Locations tab:
| id | name | address | city | phone | email | hours | lat | lng | image |
Testimonials tab:
| id | name | title | avatar | rating | text |
WhyUs tab:
| id | title | description | icon |
Icons: shield, star, clock, headphones
Settings tab (single row):
| ownerName | ownerWhatsApp | businessEmail | businessPhone | businessHours | socialLinks |
ownerWhatsApp: just the number, e.g.15550000000socialLinks: JSON object{"facebook":"url","instagram":"url"}
- In your sheet, go to Extensions > Apps Script
- Delete any default code and paste the contents of
scripts/sheets-endpoint.gs - Save (Ctrl+S) — name it anything
- Click Deploy > New Deployment
- Choose Web App
- Execute as: Me
- Who has access: Anyone
- Click Deploy, then copy the Web App URL
Create .env.local in the project root:
NEXT_PUBLIC_SHEET_JSON_URL=https://script.google.com/.../exec
NEXT_PUBLIC_SITE_URL=http://localhost:3000
Restart the dev server. Your content will now load from the sheet.
Change data in the sheet → refresh the page → site updates. No code changes needed.
Edit the CSS variables in src/app/globals.css:
--color-accent: #c9a84c; /* gold */
--color-accent-hover: #dbb956;
--color-glow: rgba(201, 168, 76, 0.15);Swap to emerald: #10b981 / #34d399 / rgba(16, 185, 129, 0.15)
Update the Google Font imports in src/app/[locale]/layout.tsx.
Set in the Settings tab of your Google Sheet. Override at any time without touching code.
src/
├── app/
│ ├── [locale]/ # Localized routes (en, fr, ar)
│ │ ├── cars/[slug]/ # Dynamic car detail pages
│ │ ├── layout.tsx # Root layout with fonts, nav, footer
│ │ └── page.tsx # Home page (all sections)
│ ├── api/settings/ # Settings API route
│ ├── globals.css # Theme variables + utility classes
│ ├── sitemap.ts # Dynamic sitemap generation
│ └── robots.ts # Robots.txt generation
├── components/
│ ├── layout/ # Navbar, Footer, WhatsAppButton, CustomCursor
│ ├── sections/ # Hero, FleetGrid, WhyChooseUs, Locations, etc.
│ └── ui/ # CarCard, AnimatedCounter, AnimatedSection
├── hooks/ # useMediaQuery
├── lib/ # sheets.ts, whatsapp.ts, utils.ts
├── messages/ # en.json, fr.json, ar.json
├── types/ # TypeScript interfaces
├── i18n.ts # next-intl config
├── middleware.ts # Locale detection
└── routing.ts # Navigation helpers
npm run build
npm startDeploy to Vercel, Netlify, or any Node.js host. Set the two env vars in your host's dashboard.
- Next.js 14 (App Router)
- TypeScript
- Tailwind CSS 3
- Framer Motion 11
- next-intl 3
- Lucide React icons
Live Demo · Built with Next.js · © Onyx Rentals







