Skip to content

Commit

Permalink
Fix #5674 Append crossOrigin on the client side too, add config optio…
Browse files Browse the repository at this point in the history
…n for crossOrigin (#5873)

# Fixes #5674

This adds config option
```js
// next.config.js
module.exports = {
  crossOrigin: 'anonymous'
}
```
This config option is defined in the webpack Define Plugin at build.
`Head` and `NextScript` now use the config option, if it's not explicitly set on the element.
This value is now passed to Webpack so it can add it to scripts that it loads.
The value is now used in `PageLoader` (on the client) so it can add it to the scripts and links that it loads.
Using `<Head crossOrigin>` or `<NextScript crossOrigin>` is now deprecated.
  • Loading branch information
dav-is authored and timneutkens committed Dec 13, 2018
1 parent 5e3bf6e commit 419bec0
Show file tree
Hide file tree
Showing 7 changed files with 53 additions and 21 deletions.
20 changes: 20 additions & 0 deletions errors/doc-crossorigin-deprecated.md
@@ -0,0 +1,20 @@
# `Head` or `NextScript` attribute `crossOrigin` is deprecated

#### Why This Error Occurred

This option has been moved to `next.config.js`.

#### Possible Ways to Fix It

Add the config option:

```js
// next.config.js
module.exports = {
crossOrigin: 'anonymous'
}
```

### Useful Links

- [The issue this was reported in: #5674](https://github.com/zeit/next.js/issues/5674)
12 changes: 6 additions & 6 deletions packages/next/README.md
Expand Up @@ -1526,13 +1526,13 @@ module.exports = {
Note: Next.js will automatically use that prefix in the scripts it loads, but this has no effect whatsoever on `/static`. If you want to serve those assets over the CDN, you'll have to introduce the prefix yourself. One way of introducing a prefix that works inside your components and varies by environment is documented [in this example](https://github.com/zeit/next.js/tree/master/examples/with-universal-configuration).
If your CDN is on a separate domain and you would like assets to be requested using a [CORS aware request](https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_settings_attributes) you can extend _document.js and specify the `crossOrigin` attribute on Head and NextScripts which is then used for all Next.js asset tags.
If your CDN is on a separate domain and you would like assets to be requested using a [CORS aware request](https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_settings_attributes) you can set a config option for that.
```js
<Head crossOrigin="anonymous">...</Head>
<body>
<Main/>
<NextScript crossOrigin="anonymous"/>
</body>
// next.config.js
module.exports = {
crossOrigin: 'anonymous'
}
```
## Production deployment
Expand Down
2 changes: 2 additions & 0 deletions packages/next/build/webpack-config.js
Expand Up @@ -258,6 +258,7 @@ export default async function getBaseWebpackConfig (dir, {dev = false, isServer
// This saves chunks with the name given via `import()`
chunkFilename: isServer ? `${dev ? '[name]' : '[name].[contenthash]'}.js` : `static/chunks/${dev ? '[name]' : '[name].[contenthash]'}.js`,
strictModuleExceptionHandling: true,
crossOriginLoading: config.crossOrigin,
webassemblyModuleFilename: 'static/wasm/[modulehash].wasm'
},
performance: { hints: false },
Expand Down Expand Up @@ -327,6 +328,7 @@ export default async function getBaseWebpackConfig (dir, {dev = false, isServer
!dev && new webpack.HashedModuleIdsPlugin(),
// Removes server/client code by minifier
new webpack.DefinePlugin({
'process.crossOrigin': JSON.stringify(config.crossOrigin),
'process.browser': JSON.stringify(!isServer)
}),
// This is used in client/dev-error-overlay/hot-dev-client.js to replace the dist directory
Expand Down
2 changes: 2 additions & 0 deletions packages/next/client/page-loader.js
Expand Up @@ -83,6 +83,7 @@ export default class PageLoader {

const script = document.createElement('script')
const url = `${this.assetPrefix}/_next/static/${encodeURIComponent(this.buildId)}/pages${scriptRoute}`
script.crossOrigin = process.crossOrigin
script.src = url
script.onerror = () => {
const error = new Error(`Error when loading route: ${route}`)
Expand Down Expand Up @@ -137,6 +138,7 @@ export default class PageLoader {
if (hasPreload) {
const link = document.createElement('link')
link.rel = 'preload'
link.crossOrigin = process.crossOrigin
link.href = `${this.assetPrefix}/_next/static/${encodeURIComponent(this.buildId)}/pages${scriptRoute}`
link.as = 'script'
document.head.appendChild(link)
Expand Down
31 changes: 18 additions & 13 deletions packages/next/pages/_document.js
Expand Up @@ -61,7 +61,7 @@ export class Head extends Component {
nonce={this.props.nonce}
rel='stylesheet'
href={`${assetPrefix}/_next/${file}`}
crossOrigin={this.props.crossOrigin}
crossOrigin={this.props.crossOrigin || process.crossOrigin}
/>
})
}
Expand All @@ -75,7 +75,7 @@ export class Head extends Component {
href={`${assetPrefix}/_next/${bundle.file}`}
as='script'
nonce={this.props.nonce}
crossOrigin={this.props.crossOrigin}
crossOrigin={this.props.crossOrigin || process.crossOrigin}
/>
})
}
Expand All @@ -98,7 +98,7 @@ export class Head extends Component {
rel='preload'
href={`${assetPrefix}/_next/${file}`}
as='script'
crossOrigin={this.props.crossOrigin}
crossOrigin={this.props.crossOrigin || process.crossOrigin}
/>
})
}
Expand All @@ -117,14 +117,15 @@ export class Head extends Component {
}
return child
})
if (this.props.crossOrigin) console.warn('Warning: `Head` attribute `crossOrigin` is deprecated. https://err.sh/next.js/doc-crossorigin-deprecated')
}

return <head {...this.props}>
{children}
{head}
{page !== '/_error' && <link rel='preload' href={`${assetPrefix}/_next/static/${buildId}/pages${pagePathname}`} as='script' nonce={this.props.nonce} crossOrigin={this.props.crossOrigin} />}
<link rel='preload' href={`${assetPrefix}/_next/static/${buildId}/pages/_app.js`} as='script' nonce={this.props.nonce} crossOrigin={this.props.crossOrigin} />
<link rel='preload' href={`${assetPrefix}/_next/static/${buildId}/pages/_error.js`} as='script' nonce={this.props.nonce} crossOrigin={this.props.crossOrigin} />
{page !== '/_error' && <link rel='preload' href={`${assetPrefix}/_next/static/${buildId}/pages${pagePathname}`} as='script' nonce={this.props.nonce} crossOrigin={this.props.crossOrigin || process.crossOrigin} />}
<link rel='preload' href={`${assetPrefix}/_next/static/${buildId}/pages/_app.js`} as='script' nonce={this.props.nonce} crossOrigin={this.props.crossOrigin || process.crossOrigin} />
<link rel='preload' href={`${assetPrefix}/_next/static/${buildId}/pages/_error.js`} as='script' nonce={this.props.nonce} crossOrigin={this.props.crossOrigin || process.crossOrigin} />
{this.getPreloadDynamicChunks()}
{this.getPreloadMainLinks()}
{this.getCssLinks()}
Expand Down Expand Up @@ -164,7 +165,7 @@ export class NextScript extends Component {
key={bundle.file}
src={`${assetPrefix}/_next/${bundle.file}`}
nonce={this.props.nonce}
crossOrigin={this.props.crossOrigin}
crossOrigin={this.props.crossOrigin || process.crossOrigin}
/>
})
}
Expand All @@ -186,7 +187,7 @@ export class NextScript extends Component {
src={`${assetPrefix}/_next/${file}`}
nonce={this.props.nonce}
async
crossOrigin={this.props.crossOrigin}
crossOrigin={this.props.crossOrigin || process.crossOrigin}
/>
})
}
Expand All @@ -201,14 +202,18 @@ export class NextScript extends Component {
const { page, buildId } = __NEXT_DATA__
const pagePathname = getPagePathname(page)

if (process.env.NODE_ENV !== 'production') {
if (this.props.crossOrigin) console.warn('Warning: `NextScript` attribute `crossOrigin` is deprecated. https://err.sh/next.js/doc-crossorigin-deprecated')
}

return <Fragment>
{devFiles ? devFiles.map((file) => <script key={file} src={`${assetPrefix}/_next/${file}`} nonce={this.props.nonce} crossOrigin={this.props.crossOrigin} />) : null}
{staticMarkup ? null : <script id="__NEXT_DATA__" type="application/json" nonce={this.props.nonce} crossOrigin={this.props.crossOrigin} dangerouslySetInnerHTML={{
{devFiles ? devFiles.map((file) => <script key={file} src={`${assetPrefix}/_next/${file}`} nonce={this.props.nonce} crossOrigin={this.props.crossOrigin || process.crossOrigin} />) : null}
{staticMarkup ? null : <script id="__NEXT_DATA__" type="application/json" nonce={this.props.nonce} crossOrigin={this.props.crossOrigin || process.crossOrigin} dangerouslySetInnerHTML={{
__html: NextScript.getInlineScriptSource(this.context._documentProps)
}} />}
{page !== '/_error' && <script async id={`__NEXT_PAGE__${page}`} src={`${assetPrefix}/_next/static/${buildId}/pages${pagePathname}`} nonce={this.props.nonce} crossOrigin={this.props.crossOrigin} />}
<script async id={`__NEXT_PAGE__/_app`} src={`${assetPrefix}/_next/static/${buildId}/pages/_app.js`} nonce={this.props.nonce} crossOrigin={this.props.crossOrigin} />
<script async id={`__NEXT_PAGE__/_error`} src={`${assetPrefix}/_next/static/${buildId}/pages/_error.js`} nonce={this.props.nonce} crossOrigin={this.props.crossOrigin} />
{page !== '/_error' && <script async id={`__NEXT_PAGE__${page}`} src={`${assetPrefix}/_next/static/${buildId}/pages${pagePathname}`} nonce={this.props.nonce} crossOrigin={this.props.crossOrigin || process.crossOrigin} />}
<script async id={`__NEXT_PAGE__/_app`} src={`${assetPrefix}/_next/static/${buildId}/pages/_app.js`} nonce={this.props.nonce} crossOrigin={this.props.crossOrigin || process.crossOrigin} />
<script async id={`__NEXT_PAGE__/_error`} src={`${assetPrefix}/_next/static/${buildId}/pages/_error.js`} nonce={this.props.nonce} crossOrigin={this.props.crossOrigin || process.crossOrigin} />
{staticMarkup ? null : this.getDynamicChunks()}
{staticMarkup ? null : this.getScripts()}
</Fragment>
Expand Down
3 changes: 3 additions & 0 deletions test/integration/app-document/next.config.js
@@ -0,0 +1,3 @@
module.exports = {
crossOrigin: 'anonymous'
}
4 changes: 2 additions & 2 deletions test/integration/app-document/pages/_document.js
Expand Up @@ -44,15 +44,15 @@ export default class MyDocument extends Document {

return (
<html>
<Head nonce='test-nonce' crossOrigin='anonymous'>
<Head nonce='test-nonce'>
{csp ? <meta httpEquiv='Content-Security-Policy' content={csp} /> : null}
<style>{`body { margin: 0 } /* custom! */`}</style>
</Head>
<body className='custom_class'>
<p id='custom-property'>{this.props.customProperty}</p>
<p id='document-hmr'>Hello Document HMR</p>
<Main />
<NextScript nonce='test-nonce' crossOrigin='anonymous' />
<NextScript nonce='test-nonce' />
</body>
</html>
)
Expand Down

0 comments on commit 419bec0

Please sign in to comment.