diff --git a/.changeset/vite-ignore-optional-imports.md b/.changeset/vite-ignore-optional-imports.md
new file mode 100644
index 00000000000..286f80132de
--- /dev/null
+++ b/.changeset/vite-ignore-optional-imports.md
@@ -0,0 +1,5 @@
+---
+"@trigger.dev/sdk": patch
+---
+
+Suppress a build-time warning that could appear in Vite-based projects when the optional `@ai-sdk/otel` package is not installed.
diff --git a/apps/webapp/app/components/StaleAssetRecovery.tsx b/apps/webapp/app/components/StaleAssetRecovery.tsx
index 7827d9ac802..32b7923921f 100644
--- a/apps/webapp/app/components/StaleAssetRecovery.tsx
+++ b/apps/webapp/app/components/StaleAssetRecovery.tsx
@@ -1,7 +1,7 @@
-// Recovers from a rolling deploy rotating the content-hashed /build assets out from
+// Recovers from a rolling deploy rotating the content-hashed /assets files out from
// under a page. Each image serves only its own build and hard-404s unknown hashes, so
// a client can request a hash the serving replica doesn't have and get missing styles
-// or a failed asset load. On such a /build load failure we do a bounded full document
+// or a failed asset load. On such an asset load failure we do a bounded full document
// reload: the fresh document (and, under sticky routing, all of its assets) lands on a
// single live build, so the asset resolves. Bounded via sessionStorage so it can never
// loop; when the budget is spent it stops rather than reloading forever.
@@ -39,7 +39,7 @@ export function staleAssetRecoveryScript() {
}
function recover() {
- // One recovery per page: a broken load fails several /build assets at once and each
+ // One recovery per page: a broken load fails several hashed assets at once and each
// fires its own error event before location.reload() commits — without this guard a
// single incident would burn the entire reload budget.
if (recovering) return;
@@ -62,7 +62,9 @@ export function staleAssetRecoveryScript() {
: el.tagName === "SCRIPT"
? (el as HTMLScriptElement).src
: null;
- if (url && url.indexOf("/build/") !== -1) recover();
+ // Match the pathname, not the full URL — a query string or third-party
+ // URL containing /assets/ must not burn the reload budget.
+ if (url && new URL(url, location.href).pathname.indexOf("/assets/") !== -1) recover();
},
true
);
diff --git a/apps/webapp/app/components/primitives/Avatar.tsx b/apps/webapp/app/components/primitives/Avatar.tsx
index 0d000a9a372..9fc6832fcc4 100644
--- a/apps/webapp/app/components/primitives/Avatar.tsx
+++ b/apps/webapp/app/components/primitives/Avatar.tsx
@@ -10,7 +10,6 @@ import {
} from "@heroicons/react/20/solid";
import type { Prisma } from "@trigger.dev/database";
import { z } from "zod";
-import { logger } from "~/services/logger.server";
import { cn } from "~/utils/cn";
export const AvatarType = z.enum(["icon", "letters", "image"]);
@@ -45,7 +44,7 @@ export function parseAvatar(json: Prisma.JsonValue, defaultAvatar: Avatar): Avat
const parsed = AvatarData.safeParse(json);
if (!parsed.success) {
- logger.error("Invalid org avatar", { json, error: parsed.error });
+ console.error("Invalid org avatar", { json, error: parsed.error });
return defaultAvatar;
}
diff --git a/apps/webapp/app/presenters/v3/UsagePresenter.server.ts b/apps/webapp/app/presenters/v3/UsagePresenter.server.ts
index fe5ab1ec3ce..a3b96cf6ac3 100644
--- a/apps/webapp/app/presenters/v3/UsagePresenter.server.ts
+++ b/apps/webapp/app/presenters/v3/UsagePresenter.server.ts
@@ -1,5 +1,8 @@
import type { DataPoint } from "regression";
-import { linear } from "regression";
+// Default-import: regression is CJS and its named exports aren't statically
+// analyzable under ESM interop.
+import regression from "regression";
+const { linear } = regression;
import type { PrismaClientOrTransaction } from "~/db.server";
import { env } from "~/env.server";
import { clickhouseFactory } from "~/services/clickhouse/clickhouseFactoryInstance.server";
diff --git a/apps/webapp/app/root.tsx b/apps/webapp/app/root.tsx
index f7c89258ad6..1c3ea631bf0 100644
--- a/apps/webapp/app/root.tsx
+++ b/apps/webapp/app/root.tsx
@@ -1,11 +1,14 @@
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 { Links, 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";
+// Fonts imported here so Vite rebases the urls and emits the woff2 assets
+import "non.geist";
+import "non.geist/mono";
+import tailwindStylesheetUrl from "~/tailwind.css?url";
import { RouteErrorDisplay } from "./components/ErrorDisplay";
import { StaleAssetRecovery } from "./components/StaleAssetRecovery";
import { AppContainer, MainCenteredContainer } from "./components/layout/AppLayout";
@@ -145,7 +148,6 @@ export default function App() {
-