Dynamic Landing Pages in Multi-Tenant Applications
Posted by

Dynamic Landing Pages in Multi-Tenant Applications
Introduction
In multi-tenant SaaS applications, each tenant often requires a unique landing page that reflects its branding and content. With Next.js, we can easily implement this using subdomain-based routing and dynamic data fetching. This guide will walk you through setting up dynamic landing pages for each tenant.
Key Concepts
- Subdomain Routing: Identifying the tenant based on the subdomain and fetching relevant content.
- Dynamic Data Fetching: Loading tenant-specific data dynamically to render the landing page.
- Custom Branding: Applying styles, logos, and themes specific to each tenant.
Subdomain-Based Routing
To begin, we will reuse our subdomain detection logic from the previous blog:
// middleware.ts
import { NextRequest, NextResponse } from "next/server";
export function middleware(req: NextRequest) {
const hostname = req.headers.get("host") || "";
const subdomain = hostname.split(".")[0];
if (subdomain && subdomain !== "www" && subdomain !== "localhost") {
req.nextUrl.searchParams.set("tenant", subdomain);
}
return NextResponse.next();
}
Fetching Landing Page Data
We fetch the tenant's branding information from our database:
// pages/index.tsx
import prisma from "@/lib/prisma";
export async function getServerSideProps({ query }) {
const { tenant } = query;
const tenantData = await prisma.tenant.findUnique({
where: { subdomain: tenant },
});
return {
props: {
tenant: tenantData || null,
},
};
}
const LandingPage = ({ tenant }) => {
if (!tenant) return <div>Tenant not found</div>;
return (
<div className="min-h-screen flex items-center justify-center bg-gray-100">
<div className="p-8 bg-white rounded-lg shadow-lg">
<img
src={`/${tenant.subdomain}-logo.png`}
alt="Logo"
className="mb-4 w-24 h-24 object-contain"
/>
<h1 className="text-3xl font-bold mb-4">Welcome to {tenant.name}</h1>
<p className="text-gray-600">{tenant.description}</p>
</div>
</div>
);
};
export default LandingPage;
Custom Branding
We can extend this by adding tenant-specific logos, themes, and even CSS classes:
- Store tenant-specific assets like logos in the
public
folder, named as<subdomain>-logo.png
. - Dynamically load the logo based on the detected subdomain, ensuring proper branding.
Conclusion
We now have a fully dynamic landing page setup for multi-tenant applications. In the next blog, we will explore Optimizing CORS for Multi-Tenant SaaS Applications, ensuring secure cross-origin requests for tenant-specific data.