Skip to content

Commit 81e76c3

Browse files
committed
Add assetPrefix support to add support for CDNs.
1 parent 6e0e7b4 commit 81e76c3

File tree

7 files changed

+35
-11
lines changed

7 files changed

+35
-11
lines changed

client/index.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,13 @@ const {
2323
err,
2424
pathname,
2525
query,
26-
buildId
26+
buildId,
27+
assetPrefix
2728
},
2829
location
2930
} = window
3031

31-
const pageLoader = new PageLoader(buildId)
32+
const pageLoader = new PageLoader(buildId, assetPrefix)
3233
window.__NEXT_LOADED_PAGES__.forEach(({ route, fn }) => {
3334
pageLoader.registerPage(route, fn)
3435
})

lib/page-loader.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,10 @@ import mitt from 'mitt'
44
const webpackModule = module
55

66
export default class PageLoader {
7-
constructor (buildId) {
7+
constructor (buildId, assetPrefix) {
88
this.buildId = buildId
9+
this.assetPrefix = assetPrefix
10+
911
this.pageCache = {}
1012
this.pageLoadedHandlers = {}
1113
this.registerEvents = mitt()
@@ -56,7 +58,7 @@ export default class PageLoader {
5658
route = this.normalizeRoute(route)
5759

5860
const script = document.createElement('script')
59-
const url = `/_next/${encodeURIComponent(this.buildId)}/page${route}`
61+
const url = `${this.assetPrefix}/_next/${encodeURIComponent(this.buildId)}/page${route}`
6062
script.src = url
6163
script.type = 'text/javascript'
6264
script.onerror = () => {

readme.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ Next.js is a minimalistic framework for server-rendered React applications.
3333
- [Custom configuration](#custom-configuration)
3434
- [Customizing webpack config](#customizing-webpack-config)
3535
- [Customizing babel config](#customizing-babel-config)
36+
- [CDN support with Asset Prefix](#cdn-support-with-asset-prefix)
3637
- [Production deployment](#production-deployment)
3738
- [FAQ](#faq)
3839
- [Roadmap](#roadmap)
@@ -700,6 +701,22 @@ Here's an example `.babelrc` file:
700701
}
701702
```
702703

704+
### CDN support with Asset Prefix
705+
706+
Sometimes, it's a pretty good idea to serve Next.js static assets via a CDN. You can easily do that by exposing the following option via `next.config.js`.
707+
708+
```js
709+
const isProd = process.NODE_ENV === 'production'
710+
module.exports = {
711+
// You may only need to add assetPrefix in the production.
712+
assetPrefix: isProd? 'https://cdn.mydomain.com' : ''
713+
}
714+
```
715+
716+
Then inside your CDN configuration, set the origin URL as your app's domain name. That's all you've to.
717+
718+
> With this setup, you can't add CDN support for static assets in the 'static' directory. This is only for core Next.js assets.
719+
703720
## Production deployment
704721

705722
To deploy, instead of running `next`, you want to build for production usage ahead of time. Therefore, building and starting are separate commands:

server/config.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ const cache = new Map()
66
const defaultConfig = {
77
webpack: null,
88
poweredByHeader: true,
9-
distDir: '.next'
9+
distDir: '.next',
10+
assetPrefix: ''
1011
}
1112

1213
export default function getConfig (dir) {

server/document.js

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -66,13 +66,13 @@ export class NextScript extends Component {
6666

6767
getChunkScript (filename, additionalProps = {}) {
6868
const { __NEXT_DATA__ } = this.context._documentProps
69-
let { buildStats } = __NEXT_DATA__
69+
let { buildStats, assetPrefix } = __NEXT_DATA__
7070
const hash = buildStats ? buildStats[filename].hash : '-'
7171

7272
return (
7373
<script
7474
type='text/javascript'
75-
src={`/_next/${hash}/${filename}`}
75+
src={`${assetPrefix}/_next/${hash}/${filename}`}
7676
{...additionalProps}
7777
/>
7878
)
@@ -97,7 +97,7 @@ export class NextScript extends Component {
9797

9898
render () {
9999
const { staticMarkup, __NEXT_DATA__ } = this.context._documentProps
100-
const { pathname, buildId } = __NEXT_DATA__
100+
const { pathname, buildId, assetPrefix } = __NEXT_DATA__
101101

102102
return <div>
103103
{staticMarkup ? null : <script dangerouslySetInnerHTML={{
@@ -111,8 +111,8 @@ export class NextScript extends Component {
111111
}
112112
`
113113
}} />}
114-
<script async type='text/javascript' src={`/_next/${buildId}/page${pathname}`} />
115-
<script async type='text/javascript' src={`/_next/${buildId}/page/_error`} />
114+
<script async type='text/javascript' src={`${assetPrefix}/_next/${buildId}/page${pathname}`} />
115+
<script async type='text/javascript' src={`${assetPrefix}/_next/${buildId}/page/_error`} />
116116
{staticMarkup ? null : this.getScripts()}
117117
</div>
118118
}

server/index.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,8 @@ export default class Server {
3636
dir: this.dir,
3737
hotReloader: this.hotReloader,
3838
buildStats: this.buildStats,
39-
buildId: this.buildId
39+
buildId: this.buildId,
40+
assetPrefix: this.config.assetPrefix.replace(/\/$/, '')
4041
}
4142

4243
this.defineRoutes()

server/render.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ async function doRender (req, res, pathname, query, {
3535
buildId,
3636
buildStats,
3737
hotReloader,
38+
assetPrefix,
3839
dir = process.cwd(),
3940
dev = false,
4041
staticMarkup = false
@@ -93,6 +94,7 @@ async function doRender (req, res, pathname, query, {
9394
query,
9495
buildId,
9596
buildStats,
97+
assetPrefix,
9698
err: (err && dev) ? errorToJSON(err) : null
9799
},
98100
dev,

0 commit comments

Comments
 (0)