diff --git a/errors/invalid-assetprefix.md b/errors/invalid-assetprefix.md new file mode 100644 index 0000000000000..a1415cfe0320b --- /dev/null +++ b/errors/invalid-assetprefix.md @@ -0,0 +1,17 @@ +# Invalid assetPrefix + +#### Why This Error Occurred + +The value of `assetPrefix` in `next.config.js` is set to something that is not a `string`. + +#### Possible Ways to Fix It + +Ensure that `assetPrefix` is a `string`. + +Example: + +```js +module.exports = { + assetPrefix: '/', +} +``` diff --git a/packages/next/next-server/server/config.ts b/packages/next/next-server/server/config.ts index f537c5fb21cd7..42b2242557d7b 100644 --- a/packages/next/next-server/server/config.ts +++ b/packages/next/next-server/server/config.ts @@ -100,6 +100,12 @@ function assignDefaults(userConfig: { [key: string]: any }) { }) const result = { ...defaultConfig, ...userConfig } + + if (typeof result.assetPrefix !== 'string') { + throw new Error( + `Specified assetPrefix is not a string, found type "${typeof result.assetPrefix}" https://err.sh/zeit/next.js/invalid-assetprefix` + ) + } if (result.experimental && result.experimental.css) { // The new CSS support requires granular chunks be enabled. result.experimental.granularChunks = true diff --git a/test/integration/invalid-config-values/pages/index.js b/test/integration/invalid-config-values/pages/index.js new file mode 100644 index 0000000000000..0957a987fc2f2 --- /dev/null +++ b/test/integration/invalid-config-values/pages/index.js @@ -0,0 +1 @@ +export default () => 'hi' diff --git a/test/integration/invalid-config-values/test/index.test.js b/test/integration/invalid-config-values/test/index.test.js new file mode 100644 index 0000000000000..df0cf1000fb21 --- /dev/null +++ b/test/integration/invalid-config-values/test/index.test.js @@ -0,0 +1,63 @@ +/* eslint-env jest */ +/* global jasmine */ +import fs from 'fs-extra' +import { join } from 'path' +import { nextBuild } from 'next-test-utils' + +const appDir = join(__dirname, '../') +const nextConfigPath = join(appDir, 'next.config.js') +jasmine.DEFAULT_TIMEOUT_INTERVAL = 1000 * 60 * 2 + +const cleanUp = () => fs.remove(nextConfigPath) + +describe('Handles valid/invalid assetPrefix', () => { + beforeAll(() => cleanUp()) + afterAll(() => cleanUp()) + + it('should not error without usage of assetPrefix', async () => { + await fs.writeFile( + nextConfigPath, + `module.exports = { + }` + ) + + const { stderr } = await nextBuild(appDir, undefined, { stderr: true }) + expect(stderr).not.toMatch(/Specified assetPrefix is not a string/) + }) + + it('should not error when assetPrefix is a string', async () => { + await fs.writeFile( + nextConfigPath, + `module.exports = { + assetPrefix: '/hello' + }` + ) + + const { stderr } = await nextBuild(appDir, undefined, { stderr: true }) + expect(stderr).not.toMatch(/Specified assetPrefix is not a string/) + }) + + it('should error on wrong usage of assetPrefix', async () => { + await fs.writeFile( + nextConfigPath, + `module.exports = { + assetPrefix: null + }` + ) + + const { stderr } = await nextBuild(appDir, undefined, { stderr: true }) + expect(stderr).toMatch(/Specified assetPrefix is not a string/) + }) + + it('should error on usage of assetPrefix with undefined as value', async () => { + await fs.writeFile( + nextConfigPath, + `module.exports = { + assetPrefix: undefined + }` + ) + + const { stderr } = await nextBuild(appDir, undefined, { stderr: true }) + expect(stderr).toMatch(/Specified assetPrefix is not a string/) + }) +})