External Marketing Website in the Next.js Supabase Turbo Starter Kit

Configure Makerkit to redirect marketing pages to an external website built with Framer, Webflow, or WordPress.

Redirect Makerkit's marketing pages to an external website by configuring the proxy.ts middleware. This lets you use Framer, Webflow, or WordPress for your marketing site while keeping Makerkit for your SaaS application.

External Marketing Website Setup

Configure redirects to your external marketing site

When to Use an External Marketing Website

Use an external marketing website when:

  • Marketing team independence: Your marketing team needs to update content without developer involvement
  • Design flexibility: You want visual builders like Framer or Webflow for landing pages
  • Content management: WordPress or a headless CMS better fits your content workflow
  • A/B testing: Your marketing tools integrate better with external platforms

Keep marketing pages in Makerkit when:

  • You want a unified codebase and deployment
  • Your team is comfortable with React and Tailwind
  • You need tight integration between marketing and app features

Configuring the Middleware

Edit apps/web/proxy.ts to redirect marketing pages:

apps/web/proxy.ts

import { type NextRequest, NextResponse } from 'next/server';
const EXTERNAL_MARKETING_URL = 'https://your-marketing-site.com';
const MARKETING_PAGES = [
'/',
'/pricing',
'/faq',
'/contact',
'/about',
'/blog',
'/privacy-policy',
'/terms-of-service',
'/cookie-policy',
];
export function proxy(req: NextRequest) {
if (isMarketingPage(req)) {
const redirectUrl = new URL(
req.nextUrl.pathname,
EXTERNAL_MARKETING_URL
);
// Preserve query parameters
redirectUrl.search = req.nextUrl.search;
return NextResponse.redirect(redirectUrl, { status: 301 });
}
// Continue with existing middleware logic
return NextResponse.next();
}
function isMarketingPage(req: NextRequest): boolean {
const pathname = req.nextUrl.pathname;
return MARKETING_PAGES.some((page) => {
if (page === '/') {
return pathname === '/';
}
return pathname === page || pathname.startsWith(`${page}/`);
});
}

Configuration Options

OptionDescription
EXTERNAL_MARKETING_URLYour external marketing site's base URL
MARKETING_PAGESArray of paths to redirect
Status code 301Permanent redirect (SEO-friendly)
Status code 302Temporary redirect (for testing)

Handling Subpaths and Assets

Blog Posts with Dynamic Paths

If your blog uses dynamic paths like /blog/post-slug, handle them separately:

const MARKETING_PAGES = [
// ... other pages
];
const MARKETING_PREFIXES = [
'/blog',
'/resources',
'/case-studies',
];
function isMarketingPage(req: NextRequest): boolean {
const pathname = req.nextUrl.pathname;
// Check exact matches
if (MARKETING_PAGES.includes(pathname)) {
return true;
}
// Check prefix matches
return MARKETING_PREFIXES.some((prefix) =>
pathname.startsWith(prefix)
);
}

Excluding Application Routes

Keep certain routes in Makerkit even if they share a marketing prefix:

const APP_ROUTES = [
'/blog/admin', // Blog admin panel stays in Makerkit
'/pricing/checkout', // Checkout flow stays in Makerkit
];
function isMarketingPage(req: NextRequest): boolean {
const pathname = req.nextUrl.pathname;
// Never redirect app routes
if (APP_ROUTES.some((route) => pathname.startsWith(route))) {
return false;
}
// ... rest of the logic
}

Verify the Redirects

After configuring, verify redirects work correctly:

# Start the development server
pnpm run dev
# Test a redirect (should return 301)
curl -I http://localhost:3000/pricing

Expected output:

HTTP/1.1 301 Moved Permanently
Location: https://your-marketing-site.com/pricing

Common Issues

Redirect loops: Ensure your external site doesn't redirect back to Makerkit.

Missing query parameters: The example code preserves query params. Verify UTM parameters pass through correctly.

Asset requests: Don't redirect asset paths like /images/ or /_next/. The middleware should only match page routes.

Environment-Based Configuration

Use environment variables for different environments:

apps/web/proxy.ts

const EXTERNAL_MARKETING_URL = process.env.EXTERNAL_MARKETING_URL;
export function proxy(req: NextRequest) {
// Only redirect if external URL is configured
if (!EXTERNAL_MARKETING_URL) {
return NextResponse.next();
}
// ... redirect logic
}

.env.production

EXTERNAL_MARKETING_URL=https://your-marketing-site.com

This lets you keep marketing pages in Makerkit during development while redirecting in production.