diff --git a/packages/fern-docs/bundle/src/middleware.ts b/packages/fern-docs/bundle/src/middleware.ts index 9a1b7dd740..0be11db993 100644 --- a/packages/fern-docs/bundle/src/middleware.ts +++ b/packages/fern-docs/bundle/src/middleware.ts @@ -3,6 +3,7 @@ import { extractNextDataPathname } from "@/server/extractNextDataPathname"; import { getLaunchDarklySettings } from "@fern-docs/edge-config"; import { removeTrailingSlash } from "@fern-docs/utils"; import { NextResponse, type NextMiddleware } from "next/server"; +import { getOrgMetadataForDomain } from "./server/auth/metadata-for-url"; import { MARKDOWN_PATTERN, RSS_PATTERN } from "./server/patterns"; import { withMiddlewareAuth } from "./server/withMiddlewareAuth"; import { withMiddlewareRewrite } from "./server/withMiddlewareRewrite"; @@ -132,7 +133,10 @@ export const middleware: NextMiddleware = async (request) => { // TODO: this adds additional latency to the page load. can we batch this somehow? const launchDarkly = await getLaunchDarklySettings( - getDocsDomainEdge(request) + getDocsDomainEdge(request), + getOrgMetadataForDomain(getDocsDomainEdge(request)).then( + (metadata) => metadata?.orgId + ) ); return withMiddlewareAuth( diff --git a/packages/fern-docs/bundle/src/server/ld-adapter.ts b/packages/fern-docs/bundle/src/server/ld-adapter.ts index 8c36802c7d..c6117aa6be 100644 --- a/packages/fern-docs/bundle/src/server/ld-adapter.ts +++ b/packages/fern-docs/bundle/src/server/ld-adapter.ts @@ -4,13 +4,17 @@ import * as ld from "@launchdarkly/node-server-sdk"; import { isEqual } from "es-toolkit/predicate"; import { camelCase } from "es-toolkit/string"; import { AuthState } from "./auth/getAuthState"; +import { getOrgMetadataForDomain } from "./auth/metadata-for-url"; async function withLaunchDarklyContext( - endpoint: string, + endpoint: string | undefined, authState: AuthState, node: FernNavigation.utils.Node, rawCookie: string | undefined ): Promise { + if (endpoint == null) { + return { kind: "user", key: "anonymous", anonymous: true }; + } try { const url = new URL(endpoint); url.searchParams.set("anonymous", String(!authState.authed)); @@ -45,7 +49,7 @@ async function withLaunchDarklyContext( interface LaunchDarklyInfo { clientSideId: string; - contextEndpoint: string; + contextEndpoint: string | undefined; context: ld.LDContext | undefined; defaultFlags: object | undefined; options: @@ -69,7 +73,10 @@ export async function withLaunchDarkly( (node: FernNavigation.WithFeatureFlags) => boolean, ] > { - const launchDarklyConfig = await getLaunchDarklySettings(domain); + const launchDarklyConfig = await getLaunchDarklySettings( + domain, + getOrgMetadataForDomain(domain).then((metadata) => metadata?.orgId) + ); if (launchDarklyConfig) { const context = await withLaunchDarklyContext( launchDarklyConfig["context-endpoint"], diff --git a/packages/fern-docs/edge-config/src/getLaunchDarklySettings.ts b/packages/fern-docs/edge-config/src/getLaunchDarklySettings.ts index 30e34bb168..cad27b42e9 100644 --- a/packages/fern-docs/edge-config/src/getLaunchDarklySettings.ts +++ b/packages/fern-docs/edge-config/src/getLaunchDarklySettings.ts @@ -10,7 +10,7 @@ const LaunchDarklyEdgeConfigSchema = z.object({ // IMPORTANT: we will pass cookies to this endpoint, so if we move this to docs.yml, // we should add a check to make sure the target domain is trusted. Trust should always be granted manually by a fern engineer, // so it should be managed in edge config, or FGA. - "context-endpoint": z.string(), + "context-endpoint": z.string().optional(), options: z .object({ @@ -26,11 +26,15 @@ export type LaunchDarklyEdgeConfig = z.infer< >; export async function getLaunchDarklySettings( - domain: string + domain: string, + orgId?: Promise ): Promise { const allConfigs = await get>("launchdarkly"); - const config = allConfigs?.[domain] ?? allConfigs?.[withoutStaging(domain)]; + const config = + allConfigs?.[domain] ?? + allConfigs?.[withoutStaging(domain)] ?? + allConfigs?.[(await orgId) ?? ""]; if (config) { const result = LaunchDarklyEdgeConfigSchema.safeParse(config); if (result.success) { diff --git a/packages/fern-docs/ui/src/atoms/types.ts b/packages/fern-docs/ui/src/atoms/types.ts index 9c835410e7..3d845ed641 100644 --- a/packages/fern-docs/ui/src/atoms/types.ts +++ b/packages/fern-docs/ui/src/atoms/types.ts @@ -54,7 +54,7 @@ export type NavbarLink = DefaultNavbarLink | GithubNavbarLink; export interface LaunchDarklyInfo { clientSideId: string; - contextEndpoint: string; + contextEndpoint: string | undefined; context: LDContext | undefined; defaultFlags: object | undefined; options: diff --git a/packages/fern-docs/ui/src/feature-flags/LDFeatureFlagProvider.tsx b/packages/fern-docs/ui/src/feature-flags/LDFeatureFlagProvider.tsx index 9cc5954f84..6b509b0567 100644 --- a/packages/fern-docs/ui/src/feature-flags/LDFeatureFlagProvider.tsx +++ b/packages/fern-docs/ui/src/feature-flags/LDFeatureFlagProvider.tsx @@ -14,7 +14,7 @@ interface Props extends PropsWithChildren { /** * The endpoint to fetch the user context from. */ - contextEndpoint: string; + contextEndpoint: string | undefined; /** * Default anonymous user context. @@ -32,6 +32,12 @@ interface Props extends PropsWithChildren { }; } +const ANONYMOUS_CONTEXT: LDContext = { + kind: "user", + key: "anonymous", + anonymous: true, +}; + export const LDFeatureFlagProvider: FC = ({ clientSideId, contextEndpoint, @@ -43,16 +49,20 @@ export const LDFeatureFlagProvider: FC = ({ return ( - - {children} - + {contextEndpoint ? ( + + {children} + + ) : ( + children + )} ); };