Skip to content

Commit 11b2e84

Browse files
committed
Add domain-based configuration and update middleware logic
This commit introduces domain-specific configurations by creating a `DomainConfig` object and utility to fetch configurations based on domain. It also updates the middleware to utilize these configurations for redirects and environment-based setups, ensuring a more flexible and domain-driven behavior. Additionally, renames `actions.ts` to `trialActions.ts` for clarity. Took 21 minutes
1 parent 6f8d13b commit 11b2e84

File tree

8 files changed

+76
-14
lines changed

8 files changed

+76
-14
lines changed

app/dfda/trials/search/page.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { Suspense } from 'react'
22
import { ArrowLeft } from 'lucide-react'
33
import Link from 'next/link'
4-
import { searchTrials } from '../actions'
4+
import { searchTrials } from '../trialActions'
55
import TrialsList from '../components/TrialsList'
66
import AdvancedTrialSearch from '../../components/AdvancedTrialSearch'
77

File renamed without changes.

config/domains.ts

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import { z } from "zod"
2+
3+
export const DomainConfig = z.object({
4+
name: z.string(),
5+
description: z.string(),
6+
author: z.string().optional(),
7+
keywords: z.string().optional(),
8+
defaultHomepage: z.string(),
9+
afterLoginPath: z.string(),
10+
ogImage: z.string().url().optional(),
11+
})
12+
13+
export type DomainConfigType = z.infer<typeof DomainConfig>
14+
15+
export const domainConfigs: Record<string, DomainConfigType> = {
16+
"wishonia.love": {
17+
name: "Wishonia",
18+
description: "Using collective intelligence to maximize median health and happiness.",
19+
author: "mikepsinn",
20+
keywords: "collective intelligence, health, happiness",
21+
defaultHomepage: "/",
22+
afterLoginPath: "/dashboard",
23+
ogImage: "https://wishonia.love/og.png"
24+
},
25+
"dfda.earth": {
26+
name: "The Decentralized FDA",
27+
description: "Crowdsourcing clinical research",
28+
author: "mikepsinn",
29+
keywords: "clinical research, health data",
30+
defaultHomepage: "/dfda",
31+
afterLoginPath: "/dfda",
32+
ogImage: "/globalSolutions/dfda/dfda-og.png"
33+
}
34+
}

env.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// This is kind of hack to make the IDE stop complaining about:
33
// TS2339: Property NEXT_PUBLIC_APP_URL does not exist on type Readonly<{}>.
44
interface Env {
5+
TEST_DOMAIN: string
56
NODE_ENV: string
67
// Add other environment variables as needed
78
NEXT_PUBLIC_APP_URL: string

env.mjs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ export const env = createEnv({
1212
DATABASE_URL: z.string().min(1),
1313
EMAIL_SERVER: z.string().min(1),
1414
EMAIL_FROM: z.string().min(1),
15+
TEST_DOMAIN: z.string().optional(),
1516
},
1617
client: {
1718
NEXT_PUBLIC_APP_URL: z.string().min(1),
@@ -22,6 +23,7 @@ export const env = createEnv({
2223
NEXT_PUBLIC_SITE_OG_IMAGE: z.string().url().optional(),
2324
NEXT_PUBLIC_DEFAULT_HOMEPAGE: z.string().optional(),
2425
NEXT_PUBLIC_DEFAULT_AFTER_LOGIN_PATH: z.string().optional(),
26+
NEXT_PUBLIC_TEST_DOMAIN: z.string().optional(),
2527
},
2628
runtimeEnv: {
2729
NEXTAUTH_URL: process.env.NEXTAUTH_URL,
@@ -41,5 +43,7 @@ export const env = createEnv({
4143
EMAIL_FROM: process.env.EMAIL_FROM,
4244
NEXT_PUBLIC_DEFAULT_HOMEPAGE: process.env.NEXT_PUBLIC_DEFAULT_HOMEPAGE,
4345
NEXT_PUBLIC_DEFAULT_AFTER_LOGIN_PATH: process.env.NEXT_PUBLIC_DEFAULT_AFTER_LOGIN_PATH,
46+
TEST_DOMAIN: process.env.TEST_DOMAIN,
47+
NEXT_PUBLIC_TEST_DOMAIN: process.env.NEXT_PUBLIC_TEST_DOMAIN,
4448
},
4549
})

lib/utils/domain-config.ts

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import { headers } from 'next/headers'
2+
import { domainConfigs, DomainConfigType } from '@/config/domains'
3+
import { env } from '@/env.mjs'
4+
5+
export function getDomainConfig(hostname?: string | null): DomainConfigType {
6+
// Use TEST_DOMAIN from env if set (for local development)
7+
if (env.TEST_DOMAIN) {
8+
return domainConfigs[env.TEST_DOMAIN] || domainConfigs["wishonia.love"]
9+
}
10+
11+
// If hostname is not provided, try to get it from headers (server-side)
12+
if (!hostname) {
13+
try {
14+
const headersList = headers()
15+
hostname = headersList.get('host')
16+
} catch (e) {
17+
// Fallback to default if headers() fails
18+
return domainConfigs["wishonia.love"]
19+
}
20+
}
21+
22+
// Clean the hostname (remove port and www.)
23+
const cleanHostname = hostname?.replace(/:\d+$/, '').replace(/^www\./, '')
24+
25+
// Return config for domain or default
26+
return domainConfigs[cleanHostname || ""] || domainConfigs["wishonia.love"]
27+
}

middleware.ts

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { NextResponse } from "next/server"
22
import { getToken } from "next-auth/jwt"
33
import { withAuth } from "next-auth/middleware"
4-
import { env } from "./env.mjs"
4+
import { getDomainConfig } from "@/lib/utils/domain-config"
55

66
export default withAuth(
77
async function middleware(req) {
@@ -11,25 +11,21 @@ export default withAuth(
1111
req.nextUrl.pathname.startsWith("/signin") ||
1212
req.nextUrl.pathname.startsWith("/signup")
1313

14-
// Use the environment variable for the default redirect, fallback to "/dashboard"
15-
const defaultRedirect = env.NEXT_PUBLIC_DEFAULT_AFTER_LOGIN_PATH || "/dashboard"
14+
const hostname = req.headers.get('host')
15+
const domainConfig = getDomainConfig(hostname)
1616

17-
// Check for the custom homepage
18-
const customHomepage = env.NEXT_PUBLIC_DEFAULT_HOMEPAGE
19-
20-
console.log(`customHomepage is: ${customHomepage} and current url is: ${req.nextUrl.pathname}`)
17+
// Check if we're on the root path
18+
if (req.nextUrl.pathname === "/") {
19+
return NextResponse.redirect(new URL(domainConfig.defaultHomepage, req.url))
20+
}
2121

22+
// Handle auth pages
2223
if (isAuthPage) {
2324
if (isAuth) {
24-
return NextResponse.redirect(new URL(defaultRedirect, req.url))
25+
return NextResponse.redirect(new URL(domainConfig.afterLoginPath, req.url))
2526
}
2627
return null
2728
}
28-
29-
// Redirect to custom homepage if set and on root path
30-
if (req.nextUrl.pathname === "/" && customHomepage) {
31-
return NextResponse.redirect(new URL(customHomepage, req.url))
32-
}
3329
},
3430
{
3531
callbacks: {
114 KB
Loading

0 commit comments

Comments
 (0)