Skip to content

feat: transformAssets#7009

Merged
schiller-manuel merged 3 commits intomainfrom
transformAssets
Mar 22, 2026
Merged

feat: transformAssets#7009
schiller-manuel merged 3 commits intomainfrom
transformAssets

Conversation

@schiller-manuel
Copy link
Contributor

@schiller-manuel schiller-manuel commented Mar 22, 2026

replaces transformAssetUrls

Summary by CodeRabbit

  • New Features

    • Configure crossOrigin on manifest-managed modulepreload and stylesheet links via a new assetCrossOrigin prop across frameworks.
    • Asset transforms can now return objects with href and optional crossOrigin per asset kind.
    • New kind-aware transform API (transformAssets) supersedes the older transformAssetUrls (deprecated, still supported).
  • Documentation

    • Added guides explaining transformAssets usage, assetCrossOrigin behavior, precedence, and migration notes.
  • Tests

    • Added SSR tests verifying crossorigin attributes and transform behaviors.

replaces transformAssetUrls
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 22, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 3a0e86d5-4ba9-40d6-9272-bb8240eae66b

📥 Commits

Reviewing files that changed from the base of the PR and between b04c703 and 450dfc9.

📒 Files selected for processing (2)
  • packages/start-server-core/src/transformAssetUrls.ts
  • packages/start-server-core/tests/transformAssets.test.ts
✅ Files skipped from review due to trivial changes (1)
  • packages/start-server-core/tests/transformAssets.test.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/start-server-core/src/transformAssetUrls.ts

📝 Walkthrough

Walkthrough

Adds a kind-aware transformAssets pipeline and HeadContent assetCrossOrigin prop, changing manifest preload/link shapes to allow { href, crossOrigin? }, updating servers, transforms, head utilities across frameworks, tests, e2e wiring, and providing adapters/deprecation for the old transformAssetUrls API.

Changes

Cohort / File(s) Summary
Documentation
docs/router/guide/document-head-management.md, docs/start/framework/react/guide/cdn-asset-urls.md
Documented assetCrossOrigin, replaced transformAssetUrls with transformAssets in examples and tables, updated callback contract, caching notes, and deprecation guidance.
Core manifest types & helpers
packages/router-core/src/manifest.ts, packages/router-core/src/index.ts
Added AssetCrossOrigin, AssetCrossOriginConfig, ManifestAssetLink, getAssetCrossOrigin, resolveManifestAssetLink; changed Manifest.preloads to Array<ManifestAssetLink> and re-exported helpers.
Start server transform infra
packages/start-server-core/src/transformAssetUrls.ts, packages/start-server-core/src/createStartHandler.ts, packages/start-server-core/src/index.tsx, packages/start-server-core/src/router-manifest.ts
Introduced transformAssets types/runtime, transformManifestAssets, adapters for legacy transformAssetUrls, updated warmup/cache semantics, and threaded preload/link shape changes through manifest generation.
HeadContent & utilities (React/Solid/Vue)
packages/*-router/src/HeadContent.tsx, packages/*-router/src/HeadContent.dev.tsx, packages/*-router/src/headContentUtils.tsx
HeadContent components now accept assetCrossOrigin prop; useTags accepts it and applies derived crossorigin to modulepreload and stylesheet links (falling back to manifest values).
Framework tests
packages/react-router/tests/Scripts.test.tsx, packages/solid-router/tests/Scripts.test.tsx, packages/vue-router/tests/Scripts.test.tsx
Added SSR tests asserting crossorigin attributes on manifest-generated modulepreload and stylesheet links and that preloads are included.
Start-server tests
packages/start-server-core/tests/transformAssets.test.ts
New tests for resolveTransformAssetsConfig, adapters, and transformManifestAssets covering shorthands, per-kind crossOrigin behavior, cloning semantics, and legacy adaptation.
E2E / transform-assets suite
e2e/react-start/transform-asset-urls/...
package.json, playwright.config.ts, src/server.ts, src/routes/__root.tsx, src/routes/index.tsx, tests/cdn-server.mjs, tests/transform-asset-urls.spec.ts
Renamed env vars to TRANSFORM_ASSETS_*, added USE_DEPRECATED_TRANSFORM_ASSET_URLS flag and deprecated test runs, updated server wiring to supply either new transformAssets or legacy adapter, adjusted CDN CORS behavior, and updated app/tests to assert crossOrigin.
E2E route typings / SSR flag
e2e/react-start/basic-rsc/src/routeTree.gen.ts, e2e/react-start/clerk-basic/src/routeTree.gen.ts
Generated typing fixes: some fullPath entries changed from '''/', and one file adds ssr: true to the Start registration augmentation.
Manifest builder / preload dedupe
packages/start-plugin-core/src/start-manifest-plugin/manifestBuilder.ts
Dedupe logic updated to resolve ManifestAssetLink to .href for preload deduplication and adjusted types to use ManifestAssetLink.

Sequence Diagram(s)

sequenceDiagram
    participant DevServer as Dev/Start Handler
    participant Transform as transformAssets
    participant Manifest as Start Manifest
    participant Head as HeadContent / useTags
    participant Browser as Browser / CDN

    DevServer->>Manifest: load manifest (routes, assets, preloads)
    DevServer->>Transform: request transform per asset (kind, url)
    Transform-->>DevServer: { href, crossOrigin? }
    DevServer->>Manifest: apply transformed href/crossOrigin
    Browser->>Head: request page (SSR/CSR)
    Head->>Manifest: read manifest-managed assets/preloads
    Head->>Browser: emit <link rel="modulepreload|stylesheet" href=... crossorigin=...>
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~70 minutes

Possibly related PRs

Poem

🐰 I hopped through manifests bright and vast,

I swapped plain URLs for hrefs and crossOrigin cast.
Modulepreload anon, stylesheet with creds,
HeadContent strings on links and careful threads —
A gentle adaption, old ways kindly passed!

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 34.62% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title 'feat: transformAssets' accurately reflects the primary change in the changeset. This PR introduces a new feature that replaces the deprecated transformAssetUrls with a more capable transformAssets system.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch transformAssets

Comment @coderabbitai help to get the list of available commands and usage tips.

@nx-cloud
Copy link

nx-cloud bot commented Mar 22, 2026

🤖 Nx Cloud AI Fix Eligible

An automatically generated fix could have helped fix failing tasks for this run, but Self-healing CI is disabled for this workspace. Visit workspace settings to enable it and get automatic fixes in future runs.

To disable these notifications, a workspace admin can disable them in workspace settings.


View your CI Pipeline Execution ↗ for commit 450dfc9

Command Status Duration Result
nx affected --targets=test:eslint,test:unit,tes... ❌ Failed 9m 19s View ↗
nx run-many --target=build --exclude=examples/*... ✅ Succeeded 34s View ↗

☁️ Nx Cloud last updated this comment at 2026-03-22 12:10:51 UTC

@github-actions
Copy link
Contributor

github-actions bot commented Mar 22, 2026

🚀 Changeset Version Preview

No changeset entries found. Merging this PR will not cause a version bump for any packages.

@github-actions
Copy link
Contributor

github-actions bot commented Mar 22, 2026

Bundle Size Benchmarks

  • Commit: 67d9e69d72ef
  • Measured at: 2026-03-22T12:07:31.481Z
  • Baseline source: history:c9e18555f3a5
  • Dashboard: bundle-size history
Scenario Current (gzip) Delta vs baseline Raw Brotli Trend
react-router.minimal 88.15 KiB 0 B (0.00%) 278.36 KiB 76.56 KiB ▁▁▁▁██████▅
react-router.full 91.38 KiB +77 B (+0.08%) 289.35 KiB 79.21 KiB ▁▁▁▁██████▅▆
solid-router.minimal 35.80 KiB 0 B (0.00%) 108.26 KiB 32.08 KiB ████▃▃▃▃▃▃▁
solid-router.full 40.22 KiB +70 B (+0.17%) 121.66 KiB 36.01 KiB ████▃▃▃▃▃▃▁▁
vue-router.minimal 53.78 KiB 0 B (0.00%) 154.49 KiB 48.23 KiB ▁▁▁▁██████▆
vue-router.full 58.64 KiB +96 B (+0.16%) 169.97 KiB 52.52 KiB ▁▁▁▁██████▆▇
react-start.minimal 102.56 KiB +121 B (+0.12%) 326.38 KiB 88.64 KiB ▁▁▁▁██████▄▅
react-start.full 105.95 KiB +97 B (+0.09%) 336.69 KiB 91.49 KiB ▁▁▁▁██████▅▅
solid-start.minimal 49.87 KiB 0 B (0.00%) 154.45 KiB 43.93 KiB ████▃▃▃▃▃▃▁
solid-start.full 55.35 KiB +99 B (+0.17%) 170.54 KiB 48.62 KiB ████▄▄▄▄▄▄▁▂

Trend sparkline is historical gzip bytes ending with this PR measurement; lower is better.

@pkg-pr-new
Copy link

pkg-pr-new bot commented Mar 22, 2026

More templates

@tanstack/arktype-adapter

npm i https://pkg.pr.new/@tanstack/arktype-adapter@7009

@tanstack/eslint-plugin-router

npm i https://pkg.pr.new/@tanstack/eslint-plugin-router@7009

@tanstack/history

npm i https://pkg.pr.new/@tanstack/history@7009

@tanstack/nitro-v2-vite-plugin

npm i https://pkg.pr.new/@tanstack/nitro-v2-vite-plugin@7009

@tanstack/react-router

npm i https://pkg.pr.new/@tanstack/react-router@7009

@tanstack/react-router-devtools

npm i https://pkg.pr.new/@tanstack/react-router-devtools@7009

@tanstack/react-router-ssr-query

npm i https://pkg.pr.new/@tanstack/react-router-ssr-query@7009

@tanstack/react-start

npm i https://pkg.pr.new/@tanstack/react-start@7009

@tanstack/react-start-client

npm i https://pkg.pr.new/@tanstack/react-start-client@7009

@tanstack/react-start-server

npm i https://pkg.pr.new/@tanstack/react-start-server@7009

@tanstack/router-cli

npm i https://pkg.pr.new/@tanstack/router-cli@7009

@tanstack/router-core

npm i https://pkg.pr.new/@tanstack/router-core@7009

@tanstack/router-devtools

npm i https://pkg.pr.new/@tanstack/router-devtools@7009

@tanstack/router-devtools-core

npm i https://pkg.pr.new/@tanstack/router-devtools-core@7009

@tanstack/router-generator

npm i https://pkg.pr.new/@tanstack/router-generator@7009

@tanstack/router-plugin

npm i https://pkg.pr.new/@tanstack/router-plugin@7009

@tanstack/router-ssr-query-core

npm i https://pkg.pr.new/@tanstack/router-ssr-query-core@7009

@tanstack/router-utils

npm i https://pkg.pr.new/@tanstack/router-utils@7009

@tanstack/router-vite-plugin

npm i https://pkg.pr.new/@tanstack/router-vite-plugin@7009

@tanstack/solid-router

npm i https://pkg.pr.new/@tanstack/solid-router@7009

@tanstack/solid-router-devtools

npm i https://pkg.pr.new/@tanstack/solid-router-devtools@7009

@tanstack/solid-router-ssr-query

npm i https://pkg.pr.new/@tanstack/solid-router-ssr-query@7009

@tanstack/solid-start

npm i https://pkg.pr.new/@tanstack/solid-start@7009

@tanstack/solid-start-client

npm i https://pkg.pr.new/@tanstack/solid-start-client@7009

@tanstack/solid-start-server

npm i https://pkg.pr.new/@tanstack/solid-start-server@7009

@tanstack/start-client-core

npm i https://pkg.pr.new/@tanstack/start-client-core@7009

@tanstack/start-fn-stubs

npm i https://pkg.pr.new/@tanstack/start-fn-stubs@7009

@tanstack/start-plugin-core

npm i https://pkg.pr.new/@tanstack/start-plugin-core@7009

@tanstack/start-server-core

npm i https://pkg.pr.new/@tanstack/start-server-core@7009

@tanstack/start-static-server-functions

npm i https://pkg.pr.new/@tanstack/start-static-server-functions@7009

@tanstack/start-storage-context

npm i https://pkg.pr.new/@tanstack/start-storage-context@7009

@tanstack/valibot-adapter

npm i https://pkg.pr.new/@tanstack/valibot-adapter@7009

@tanstack/virtual-file-routes

npm i https://pkg.pr.new/@tanstack/virtual-file-routes@7009

@tanstack/vue-router

npm i https://pkg.pr.new/@tanstack/vue-router@7009

@tanstack/vue-router-devtools

npm i https://pkg.pr.new/@tanstack/vue-router-devtools@7009

@tanstack/vue-router-ssr-query

npm i https://pkg.pr.new/@tanstack/vue-router-ssr-query@7009

@tanstack/vue-start

npm i https://pkg.pr.new/@tanstack/vue-start@7009

@tanstack/vue-start-client

npm i https://pkg.pr.new/@tanstack/vue-start-client@7009

@tanstack/vue-start-server

npm i https://pkg.pr.new/@tanstack/vue-start-server@7009

@tanstack/zod-adapter

npm i https://pkg.pr.new/@tanstack/zod-adapter@7009

commit: 450dfc9

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/start-server-core/src/createStartHandler.ts (1)

472-490: ⚠️ Potential issue | 🟠 Major

Don’t memoize a failed or dev-only createTransform() call.

This promise is cached even when TSS_DEV_SERVER === 'true', and a sync/async failure on the first request stays cached forever. That makes dev miss the documented cache bypass and turns a transient createTransform() failure into a process-wide outage until restart.

Suggested change
-      if (cache) {
+      if (cache && process.env.TSS_DEV_SERVER !== 'true') {
         if (!cachedCreateTransformPromise) {
-          cachedCreateTransformPromise = Promise.resolve(
-            resolvedTransformConfig.createTransform(opts),
-          )
+          cachedCreateTransformPromise = Promise.resolve()
+            .then(() => resolvedTransformConfig.createTransform(opts))
+            .catch((error) => {
+              cachedCreateTransformPromise = undefined
+              throw error
+            })
         }
         return cachedCreateTransformPromise
       }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/start-server-core/src/createStartHandler.ts` around lines 472 - 490,
The cachedCreateTransformPromise is being stored unconditionally which preserves
failures and ignores the dev-server cache-bypass; modify getTransformFn (and use
of cachedCreateTransformPromise) so that caching only occurs when cache is
enabled and process.env.TSS_DEV_SERVER !== 'true', and ensure you never store a
permanently rejected promise: when you create the promise from
resolvedTransformConfig.createTransform(opts) wrap it so on rejection you clear
cachedCreateTransformPromise (set it back to undefined) before re-throwing the
error; keep the same return behavior for resolvedTransformConfig.transformFn
when type !== 'createTransform'.
🧹 Nitpick comments (1)
e2e/react-start/transform-asset-urls/src/server.ts (1)

6-16: Consider importing TransformAssetsFn from the package instead of redefining it locally.

The local type definition duplicates the type exported from @tanstack/react-start/server. Importing it directly would keep the e2e test aligned with the actual package type and avoid drift.

♻️ Suggested import
-import type { TransformAssetUrls } from '@tanstack/react-start/server'
-
-type TransformAssetsFn = (ctx: {
-  kind: 'modulepreload' | 'stylesheet' | 'clientEntry'
-  url: string
-}) =>
-  | string
-  | {
-      href: string
-      crossOrigin?: 'anonymous' | 'use-credentials'
-    }
+import type {
+  TransformAssetsFn,
+  TransformAssetUrls,
+} from '@tanstack/react-start/server'
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@e2e/react-start/transform-asset-urls/src/server.ts` around lines 6 - 16,
Replace the local duplicated type alias TransformAssetsFn with the exported type
from the package by adding an import for TransformAssetsFn from
'@tanstack/react-start/server' (alongside the existing TransformAssetUrls
import) and remove the local type definition; update any references to use the
imported TransformAssetsFn type (search for the symbol TransformAssetsFn and the
local type block) so the test uses the canonical type from the package.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@packages/start-server-core/src/createStartHandler.ts`:
- Around line 441-456: The selection logic currently uses truthy checks so an
explicit empty-string config (valid no-op) is treated as absent; change the
ternary conditions to explicit undefined checks: use "transformAssetsOption !==
undefined" and "transformAssetUrlsOption !== undefined" when computing
transformOption so empty-string values are preserved, and keep the calls to
resolveTransformAssetsConfig and adaptTransformAssetUrlsConfigToTransformAssets
exactly as written for transformAssetsOption and transformAssetUrlsOption
respectively.

In `@packages/start-server-core/src/transformAssetUrls.ts`:
- Around line 384-386: The code currently assigns manifest = opts?.clone ?
structuredClone(source.manifest) : source.manifest which lets the async rewrite
mutate the cached source.manifest when clone is false; change the logic so the
async rewrite never mutates source.manifest directly (i.e., always operate on a
copy). Specifically, replace the conditional assignment so manifest is a
structuredClone of source.manifest before the async rewrite runs (or create a
fresh deep copy immediately before calling the async rewrite routine), ensuring
the original source.manifest remains immutable and avoiding double-prefixing on
retries.
- Around line 149-151: Restrict the cross-origin shorthand so it cannot include
clientEntry: update the TransformAssetsCrossOriginConfig type (the union around
AssetCrossOrigin | Partial<Record<TransformAssetKind, AssetCrossOrigin>>) to
exclude TransformAssetKind.clientEntry from the Partial key set, or add
validation in the config resolution logic that detects and rejects a shorthand
object containing a clientEntry key; ensure the error message mentions
clientEntry is invalid for the shorthand and point users to use the full
AssetCrossOrigin shape for client-entry if needed.

---

Outside diff comments:
In `@packages/start-server-core/src/createStartHandler.ts`:
- Around line 472-490: The cachedCreateTransformPromise is being stored
unconditionally which preserves failures and ignores the dev-server
cache-bypass; modify getTransformFn (and use of cachedCreateTransformPromise) so
that caching only occurs when cache is enabled and process.env.TSS_DEV_SERVER
!== 'true', and ensure you never store a permanently rejected promise: when you
create the promise from resolvedTransformConfig.createTransform(opts) wrap it so
on rejection you clear cachedCreateTransformPromise (set it back to undefined)
before re-throwing the error; keep the same return behavior for
resolvedTransformConfig.transformFn when type !== 'createTransform'.

---

Nitpick comments:
In `@e2e/react-start/transform-asset-urls/src/server.ts`:
- Around line 6-16: Replace the local duplicated type alias TransformAssetsFn
with the exported type from the package by adding an import for
TransformAssetsFn from '@tanstack/react-start/server' (alongside the existing
TransformAssetUrls import) and remove the local type definition; update any
references to use the imported TransformAssetsFn type (search for the symbol
TransformAssetsFn and the local type block) so the test uses the canonical type
from the package.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 21495e80-71fe-4cc3-ab21-835f3fe3e65f

📥 Commits

Reviewing files that changed from the base of the PR and between 67d9e69 and 9ae82df.

📒 Files selected for processing (31)
  • docs/router/guide/document-head-management.md
  • docs/start/framework/react/guide/cdn-asset-urls.md
  • e2e/react-start/basic-rsc/src/routeTree.gen.ts
  • e2e/react-start/clerk-basic/src/routeTree.gen.ts
  • e2e/react-start/transform-asset-urls/package.json
  • e2e/react-start/transform-asset-urls/playwright.config.ts
  • e2e/react-start/transform-asset-urls/src/routes/__root.tsx
  • e2e/react-start/transform-asset-urls/src/routes/index.tsx
  • e2e/react-start/transform-asset-urls/src/server.ts
  • e2e/react-start/transform-asset-urls/tests/cdn-server.mjs
  • e2e/react-start/transform-asset-urls/tests/transform-asset-urls.spec.ts
  • packages/react-router/src/HeadContent.dev.tsx
  • packages/react-router/src/HeadContent.tsx
  • packages/react-router/src/Match.tsx
  • packages/react-router/src/headContentUtils.tsx
  • packages/react-router/tests/Scripts.test.tsx
  • packages/router-core/src/index.ts
  • packages/router-core/src/manifest.ts
  • packages/solid-router/src/HeadContent.dev.tsx
  • packages/solid-router/src/HeadContent.tsx
  • packages/solid-router/src/headContentUtils.tsx
  • packages/solid-router/tests/Scripts.test.tsx
  • packages/start-server-core/src/createStartHandler.ts
  • packages/start-server-core/src/index.tsx
  • packages/start-server-core/src/router-manifest.ts
  • packages/start-server-core/src/transformAssetUrls.ts
  • packages/start-server-core/tests/transformAssets.test.ts
  • packages/vue-router/src/HeadContent.dev.tsx
  • packages/vue-router/src/HeadContent.tsx
  • packages/vue-router/src/headContentUtils.tsx
  • packages/vue-router/tests/Scripts.test.tsx

@codspeed-hq
Copy link

codspeed-hq bot commented Mar 22, 2026

Merging this PR will not alter performance

✅ 6 untouched benchmarks


Comparing transformAssets (450dfc9) with main (c9e1855)1

Open in CodSpeed

Footnotes

  1. No successful run was found on main (67d9e69) during the generation of this report, so c9e1855 was used instead as the comparison base. There might be some changes unrelated to this pull request in this report.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
packages/start-server-core/src/transformAssetUrls.ts (1)

413-431: Consider: All <link> tags treated as stylesheets.

The transform uses kind: 'stylesheet' for all <link> tags with an href. If the manifest ever contains other link types (preconnect, preload for fonts, icons, etc.), they would be incorrectly categorized. Currently this appears safe given how assets are built, but worth documenting or adding a check for rel="stylesheet" if the manifest schema evolves.

🔧 Optional: Add explicit rel check
       if (asset.tag === 'link' && asset.attrs?.href) {
+        // Only transform stylesheet links; other link types should retain original URLs
+        const isStylesheet = asset.attrs.rel === 'stylesheet'
         const result = normalizeTransformAssetResult(
           await transformFn({
             url: asset.attrs.href,
-            kind: 'stylesheet',
+            kind: isStylesheet ? 'stylesheet' : 'modulepreload',
           }),
         )
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/start-server-core/src/transformAssetUrls.ts` around lines 413 - 431,
The loop treating every <link> with an href as a stylesheet can misclassify
other rel types; update the logic around route.assets iteration to inspect
asset.attrs?.rel (and/or asset.attrs.rel?.split(/\s+/) includes 'stylesheet')
before calling transformFn with kind: 'stylesheet', and for non-stylesheet rel
values either skip transform or map rel to an appropriate kind when calling
transformFn (use the same symbols: route.assets, asset.tag, asset.attrs.href,
asset.attrs.rel, transformFn and normalizeTransformAssetResult) so only true
stylesheet links are sent as kind 'stylesheet' and others are handled
appropriately.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@packages/start-server-core/src/transformAssetUrls.ts`:
- Around line 413-431: The loop treating every <link> with an href as a
stylesheet can misclassify other rel types; update the logic around route.assets
iteration to inspect asset.attrs?.rel (and/or asset.attrs.rel?.split(/\s+/)
includes 'stylesheet') before calling transformFn with kind: 'stylesheet', and
for non-stylesheet rel values either skip transform or map rel to an appropriate
kind when calling transformFn (use the same symbols: route.assets, asset.tag,
asset.attrs.href, asset.attrs.rel, transformFn and
normalizeTransformAssetResult) so only true stylesheet links are sent as kind
'stylesheet' and others are handled appropriately.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 92473a29-690c-4460-b801-6d34b03f9e1c

📥 Commits

Reviewing files that changed from the base of the PR and between 9ae82df and b04c703.

📒 Files selected for processing (5)
  • packages/react-router/src/Match.tsx
  • packages/start-plugin-core/src/start-manifest-plugin/manifestBuilder.ts
  • packages/start-server-core/src/createStartHandler.ts
  • packages/start-server-core/src/transformAssetUrls.ts
  • packages/start-server-core/tests/transformAssets.test.ts
✅ Files skipped from review due to trivial changes (1)
  • packages/start-server-core/tests/transformAssets.test.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • packages/react-router/src/Match.tsx
  • packages/start-server-core/src/createStartHandler.ts

@schiller-manuel schiller-manuel merged commit 6164816 into main Mar 22, 2026
16 of 17 checks passed
@schiller-manuel schiller-manuel deleted the transformAssets branch March 22, 2026 19:25
@birkskyum birkskyum mentioned this pull request Mar 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants