In a monolith

@fairgarden/monolith mounts several apps into one deployment, each under a prefix, and merges their rewrites, redirects and headers with that prefix applied. An app using this library needs three things to survive that.

The config merges

withFairGardenIndicators only adds rewrites and redirects, which the monolith knows how to merge, and puts nothing in env or anywhere else it would refuse. The chain comes out under the mount:

/:path((?!en|fr|…).+)  -> /en/:path      in the app
/id/:path((?!en|fr|…).+)  -> /id/en/:path   in the monolith

Every source and destination is prefixed, has conditions ride along, and the chain works unchanged because every step is relative to what follows the mount.

The monolith loads each app's next.config.ts with Node itself, which resolves a relative import only with its extension. Import the config's module as ./lib/indicators.ts, with allowImportingTsExtensions in the app's tsconfig.json.

Links carry the mount

The app's Link applies the locale first and the mount second, and the mount comes from the monolith's own helper:

// lib/link.ts
'use client'
import { createNavigation } from '@fairgarden/indicators/link'
import { mountPrefix } from '@fairgarden/monolith/link'
import { indicators } from '@fairgarden/id/lib/indicators'

export const { Link, useHref, useIndicators, useLocale, usePref } = createNavigation(
  indicators,
  { mount: mountPrefix('@fairgarden/id') }
)

<Link href="/settings"> on a French page is /fr/settings standalone and /id/fr/settings mounted. mountPrefix is '' when the app runs on its own, so the same module works either way; it reads MONOLITH_MOUNTS, which the monolith inlines into the bundle.

The proxy moves

A deployment has one proxy, so an app's proxy.ts is not mounted — the monolith's portability check says so. The monolith runs detection for every app it serves, at each app's root:

// apps/monolith/proxy.ts
import { createLocaleProxy } from '@fairgarden/indicators/proxy'
import { indicators as www } from '@acme/www/lib/indicators'
import { indicators as id } from '@fairgarden/id/lib/indicators'

export const proxy = createLocaleProxy({ '/': www, '/id': id })
export const config = { matcher: ['/', '/id'] }

A redirect from /id then goes to /id/fr. An app's own proxy.ts stays for running it standalone.

Cookies are shared

A preference cookie is written with Path=/, so a theme chosen in one app holds in every app of the monolith — which is what a user of one site expects. Apps that share a cookie should agree on its values, or read different cookies.