MEHDI.
RETURN_TO_INDEX

Building a Real Estate Platform for the Moroccan Market

6 min read
#React#TypeScript#Express#PostgreSQL#Real Estate#Morocco#SEO

When a real estate business needs a website, the usual options are generic WordPress themes or SaaS platforms that charge per listing. Neither gives the business full control over the codebase, the data, or the SEO strategy. I built a custom platform for a Moroccan real estate business that needed exactly that control.

The platform is a monorepo containing three applications: a public property website, an administration dashboard, and a REST API. The stack is React, Vite, TypeScript, Express, Prisma and PostgreSQL.

What the Business Needs

A real estate website serves two audiences: property seekers and the business itself. Property seekers need to browse available properties, filter by criteria, view details, and make inquiries. The business needs to manage listings, track leads, update content, and maintain an online presence.

The platform handles both sides. The public site is the storefront. The admin dashboard is the back office.

Public-Facing Pages

The public site includes:

  • Property listings: Filterable by type (apartment, villa, land), location, price range, and features
  • Property detail pages: Full descriptions, photo galleries, key information (surface area, rooms, price), and contact forms
  • Real estate projects: New development projects with floor plans, available units, and progress status
  • Agent profiles: Information about the agency's agents
  • Contact forms: Multiple entry points for inquiries about specific properties or general questions

Each property page has a clean URL with a descriptive slug, which matters for SEO. A URL like /properties/modern-apartment-casainexpensive-center tells both users and search engines what the page is about.

The Administration Dashboard

The admin dashboard allows the business to:

  • Create, edit and publish property listings
  • Manage real estate projects and their associated units
  • Add and update agent profiles
  • View and respond to leads from contact forms
  • Update general website content (about page, contact information)
  • Monitor site activity

The dashboard is protected by authentication with role-based access. Different staff members see different functions based on their role.

Architecture: Monorepo

The monorepo structure keeps related code together while maintaining clear boundaries:

apps/web/          # Public-facing React site (Vite)
apps/admin/        # Admin dashboard (Vite)
apps/api/          # Express REST API
packages/shared/   # Shared types and utilities

This structure means the public site and admin dashboard share type definitions and utilities without importing each other's code. The API serves both frontends.

The API Layer

The Express API uses Prisma to interact with PostgreSQL. It handles:

  • Property CRUD operations
  • Project management
  • Lead creation and retrieval
  • Authentication (JWT with HTTP-only cookies)
  • File uploads for property images
  • SEO metadata generation

The API is the single source of truth. Both the public site and the admin dashboard consume the same endpoints, which means there is no risk of the admin dashboard using different logic than the public site.

Authentication

Admin authentication uses JWT stored in HTTP-only cookies. This prevents JavaScript from accessing the token, which mitigates XSS attacks. The cookie is set with Secure and SameSite=Strict flags in production.

res.cookie("token", jwt, {
  httpOnly: true,
  secure: process.env.NODE_ENV === "production",
  sameSite: "strict",
  maxAge: 24 * 60 * 60 * 1000, // 24 hours
});

The admin session is relatively short-lived (24 hours) and requires re-authentication after expiry. This is a deliberate tradeoff between convenience and security for a business application.

SEO Strategy

Real estate is a local business, and local SEO matters. The platform implements several SEO best practices:

Descriptive URLs: Every property page has a slug that includes the property type and location. These are more meaningful to search engines than numeric IDs.

Metadata: Each page generates appropriate title tags, meta descriptions, and Open Graph tags. Property pages include the price, location and type in the title.

Sitemap: The sitemap includes all published property pages, project pages, and static pages. It updates automatically when properties are added or removed.

Structured data: Property pages include JSON-LD structured data (Schema.org) with information about the property type, price, location, and images. This helps search engines understand the content and can result in rich snippets in search results.

Performance: Images are optimized for web delivery. The public site is built with Vite, which produces optimized bundles with code splitting.

Leads and Contact Forms

Every contact form submission creates a lead in the database. The admin dashboard shows all leads with timestamps, the property they inquired about, and their message. This allows the business to track response times and follow up systematically.

The forms include basic validation (required fields, email format) on both client and server. Server-side validation is the authoritative check; client-side validation provides immediate feedback.

Particularities of the Moroccan Market

Building for a specific market means adapting to local expectations:

  • Language: The platform supports French and Arabic, which are the primary languages for real estate in Morocco
  • Currency: Prices are displayed in Moroccan Dirham (MAD)
  • Property types: The classification system reflects Moroccan property categories (apartment, villa, riad, terrain, bureau)
  • Location hierarchy: Properties are organized by city, then by neighborhood, following the administrative divisions used in Morocco

I did not invent legal requirements. Any mention of regulatory compliance (like CNDP data protection rules) should be verified against official sources before making specific claims.

What I Learned

A real estate platform is a content management system. The core challenge is not displaying properties; it is enabling non-technical staff to manage listings, update content, and respond to leads without developer intervention.

SEO is not an afterthought. For a local business, search visibility directly affects revenue. Designing the URL structure, metadata, and sitemap from the beginning is much easier than retrofitting them later.

Leads are the product. The public website exists to generate leads. If the contact forms do not work reliably, or if leads are not visible in the admin dashboard, the entire platform fails at its primary purpose.

Self-hosting gives control but requires maintenance. The business owns the code, the data, and the infrastructure. They also own the responsibility for updates, backups, and security. This is the right choice for a business that wants independence, but it is not the right choice for every business.

The platform evolved from a simple property listing site into a full administrative tool. Each feature was added in response to a real need, not a hypothetical one. That discipline -- building what is needed, not what is impressive -- is the most important lesson from this project.