import type { LinksFunction, LoaderFunctionArgs, MetaFunction } from "@remix-run/node"; import type { ShouldRevalidateFunction } from "@remix-run/react"; import { Links, LiveReload, Meta, Outlet, Scripts, ScrollRestoration } from "@remix-run/react"; import { type UseDataFunctionReturn, typedjson, useTypedLoaderData } from "remix-typedjson"; import { ExternalScripts } from "remix-utils/external-scripts"; import type { ToastMessage } from "~/models/message.server"; import { commitSession, getSession } from "~/models/message.server"; import tailwindStylesheetUrl from "~/tailwind.css"; import { RouteErrorDisplay } from "./components/ErrorDisplay"; import { AppContainer, MainCenteredContainer } from "./components/layout/AppLayout"; import { ShortcutsProvider } from "./components/primitives/ShortcutsProvider"; import { Toast } from "./components/primitives/Toast"; import { TimezoneSetter } from "./components/TimezoneSetter"; import { env } from "./env.server"; import { featuresForRequest } from "./features.server"; import { usePostHog } from "./hooks/usePostHog"; import { getUser } from "./services/session.server"; import { getTimezonePreference } from "./services/preferences/uiPreferences.server"; import { appEnvTitleTag } from "./utils"; export const links: LinksFunction = () => { return [{ rel: "stylesheet", href: tailwindStylesheetUrl }]; }; export const headers = () => ({ "Referrer-Policy": "strict-origin-when-cross-origin", "X-Content-Type-Options": "nosniff", "Permissions-Policy": "geolocation=(), microphone=(), camera=(), accelerometer=(), gyroscope=(), magnetometer=(), payment=(), usb=()", }); export const meta: MetaFunction = ({ data }) => { const typedData = data as UseDataFunctionReturn; return [ { title: typedData?.appEnv ? `Trigger.dev${appEnvTitleTag(typedData.appEnv)}` : "Trigger.dev" }, { name: "viewport", content: "width=1024, initial-scale=1", }, { name: "robots", content: typeof window === "undefined" || window.location.hostname !== "cloud.trigger.dev" ? "noindex, nofollow" : "index, follow", }, ]; }; export const loader = async ({ request }: LoaderFunctionArgs) => { const session = await getSession(request.headers.get("cookie")); const toastMessage = session.get("toastMessage") as ToastMessage; const posthogProjectKey = env.POSTHOG_PROJECT_KEY; const posthogUiHost = env.POSTHOG_HOST; const features = featuresForRequest(request); const timezone = await getTimezonePreference(request); const kapa = { websiteId: env.KAPA_AI_WEBSITE_ID, }; const user = await getUser(request); const headers = new Headers(); headers.append("Set-Cookie", await commitSession(session)); return typedjson( { user, toastMessage, posthogProjectKey, posthogUiHost, features, appEnv: env.APP_ENV, appOrigin: env.APP_ORIGIN, apiOrigin: env.API_ORIGIN ?? env.APP_ORIGIN, triggerCliTag: env.TRIGGER_CLI_TAG, kapa, timezone, }, { headers } ); }; export type LoaderType = typeof loader; export const shouldRevalidate: ShouldRevalidateFunction = (options) => { if (options.formAction === "/resources/environment") { return false; } return options.defaultShouldRevalidate; }; export function ErrorBoundary() { return ( <> ); } export default function App() { const { posthogProjectKey, posthogUiHost, kapa: _kapa } = useTypedLoaderData(); usePostHog(posthogProjectKey, posthogUiHost); return ( <> ); }