Skip to content

Commit 44e7843

Browse files
committed
fix: add text/x-component header to .rsc assets generated at build time, don't use rsc-data edge function when hitting .rsc path directly
1 parent 49e1974 commit 44e7843

File tree

6 files changed

+36
-16
lines changed

6 files changed

+36
-16
lines changed

packages/runtime/src/helpers/config.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,19 @@ const buildHeader = (buildHeaderParams: BuildHeaderParams) => {
217217
// configuration does not support.
218218
const sanitizePath = (path: string) => path.replace(/:[^*/]+\*$/, '*')
219219

220+
/**
221+
* Sets Content-type header for static RSC assets (text/x-component), so application/octet-stream is not used when serving them
222+
* @param netlifyHeaders - Existing headers that are already configured in the Netlify configuration
223+
*/
224+
export const addContentTypeHeaderToStaticRSCAssets = (netlifyHeaders: NetlifyHeaders = []) => {
225+
netlifyHeaders.push({
226+
for: `*.rsc`,
227+
values: {
228+
'Content-Type': 'text/x-component',
229+
},
230+
})
231+
}
232+
220233
/**
221234
* Persist Next.js custom headers to the Netlify configuration so the headers work with static files
222235
* See {@link https://nextjs.org/docs/api-reference/next.config.js/headers} for more information on custom

packages/runtime/src/helpers/edge.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -290,14 +290,14 @@ export const generateRscDataEdgeManifest = async ({
290290
const staticAppdirRoutes: Array<string> = []
291291
for (const [path, route] of Object.entries(prerenderManifest.routes)) {
292292
if (isAppDirRoute(route.srcRoute, appPathRoutesManifest) && route.dataRoute) {
293-
staticAppdirRoutes.push(path, route.dataRoute)
293+
staticAppdirRoutes.push(path)
294294
}
295295
}
296296
const dynamicAppDirRoutes: Array<string> = []
297297

298298
for (const [path, route] of Object.entries(prerenderManifest.dynamicRoutes)) {
299299
if (isAppDirRoute(path, appPathRoutesManifest) && route.dataRouteRegex) {
300-
dynamicAppDirRoutes.push(route.routeRegex, route.dataRouteRegex)
300+
dynamicAppDirRoutes.push(route.routeRegex)
301301
}
302302
}
303303

packages/runtime/src/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import {
1414
updateRequiredServerFiles,
1515
configureHandlerFunctions,
1616
generateCustomHeaders,
17+
addContentTypeHeaderToStaticRSCAssets,
1718
} from './helpers/config'
1819
import { onPreDev } from './helpers/dev'
1920
import { writeEdgeFunctions, loadMiddlewareManifest, cleanupEdgeFunctions } from './helpers/edge'
@@ -250,6 +251,7 @@ const plugin: NetlifyPlugin = {
250251

251252
const { basePath, appDir, experimental } = nextConfig
252253

254+
addContentTypeHeaderToStaticRSCAssets(headers)
253255
generateCustomHeaders(nextConfig, headers)
254256

255257
warnForProblematicUserRewrites({ basePath, redirects })

packages/runtime/src/templates/edge-shared/rsc-data.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,9 @@ export declare type PrerenderManifest = {
2828

2929
const noop = () => {}
3030

31-
// Ensure that routes with and without a trailing slash map to different ODB paths
3231
const rscifyPath = (route: string) => {
3332
if (route.endsWith('/')) {
34-
return route.slice(0, -1) + '.rsc/'
33+
return route.slice(0, -1) + '.rsc'
3534
}
3635
return route + '.rsc'
3736
}

test/helpers/edge.spec.ts

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -46,12 +46,6 @@ describe('generateRscDataEdgeManifest', () => {
4646
name: 'RSC data routing',
4747
path: '/',
4848
},
49-
{
50-
function: 'rsc-data',
51-
generator: '@netlify/next-runtime@1.0.0',
52-
name: 'RSC data routing',
53-
path: '/index.rsc',
54-
},
5549
])
5650
})
5751

@@ -99,12 +93,6 @@ describe('generateRscDataEdgeManifest', () => {
9993
name: 'RSC data routing',
10094
pattern: '^/blog/([^/]+?)(?:/)?$',
10195
},
102-
{
103-
function: 'rsc-data',
104-
generator: '@netlify/next-runtime@1.0.0',
105-
name: 'RSC data routing',
106-
pattern: '^/blog/([^/]+?)\\.rsc$',
107-
},
10896
])
10997
})
11098

test/index.spec.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -899,6 +899,12 @@ describe('onPostBuild', () => {
899899
})
900900

901901
expect(netlifyConfig.headers).toEqual([
902+
{
903+
for: `*.rsc`,
904+
values: {
905+
'Content-Type': 'text/x-component',
906+
},
907+
},
902908
{
903909
for: '/',
904910
values: {
@@ -1001,6 +1007,12 @@ describe('onPostBuild', () => {
10011007
'x-existing-header-in-configuration': 'existing header in configuration value',
10021008
},
10031009
},
1010+
{
1011+
for: `*.rsc`,
1012+
values: {
1013+
'Content-Type': 'text/x-component',
1014+
},
1015+
},
10041016
{
10051017
for: '/',
10061018
values: {
@@ -1108,6 +1120,12 @@ describe('onPostBuild', () => {
11081120
'x-existing-header-in-configuration': 'existing header in configuration value',
11091121
},
11101122
},
1123+
{
1124+
for: `*.rsc`,
1125+
values: {
1126+
'Content-Type': 'text/x-component',
1127+
},
1128+
},
11111129
])
11121130
})
11131131

0 commit comments

Comments
 (0)