diff --git a/errors/can-not-output-to-static.md b/errors/can-not-output-to-static.md new file mode 100644 index 000000000000000..b949bc06ffb7a02 --- /dev/null +++ b/errors/can-not-output-to-static.md @@ -0,0 +1,15 @@ +# Cannot output to /static + +#### Why This Error Occurred + +Either you set `distDir` to `static` in your `next.config.js` or during `next export` you tried to export to the `static` directory. + +This is not allowed due to `static` being a special folder in Next.js used to serve static assets. + +#### Possible Ways to Fix It + +Use a different `distDir` or export to a different folder. + +### Useful Links + +- [Static file serving docs](https://nextjs.org/docs/basic-features/static-file-serving) diff --git a/packages/next/export/index.ts b/packages/next/export/index.ts index fc611fccb91a5d5..c820e25c8904daf 100644 --- a/packages/next/export/index.ts +++ b/packages/next/export/index.ts @@ -252,6 +252,12 @@ export default async function exportApp( ) } + if (outDir === join(dir, 'static')) { + throw new Error( + `The 'static' directory is reserved in Next.js and can not be used as the export out directory. https://err.sh/vercel/next.js/can-not-output-to-static` + ) + } + await recursiveDelete(join(outDir)) await promises.mkdir(join(outDir, '_next', buildId), { recursive: true }) diff --git a/test/integration/errors-on-output-to-public/test/index.test.js b/test/integration/errors-on-output-to-public/test/index.test.js index b094b29a74fda1f..be7e9b9bcd1f4c2 100644 --- a/test/integration/errors-on-output-to-public/test/index.test.js +++ b/test/integration/errors-on-output-to-public/test/index.test.js @@ -13,7 +13,7 @@ describe('Errors on output to public', () => { await fs.writeFile(nextConfig, `module.exports = { distDir: 'public' }`) const results = await nextBuild(appDir, [], { stdout: true, stderr: true }) expect(results.stdout + results.stderr).toMatch( - /The 'public' directory is reserved in Next.js and can not be set as/ + /The 'public' directory is reserved in Next\.js and can not be set as/ ) await fs.remove(nextConfig) }) @@ -31,7 +31,7 @@ describe('Errors on output to public', () => { } ) expect(results.stdout + results.stderr).toMatch( - /The 'public' directory is reserved in Next.js and can not be used as/ + /The 'public' directory is reserved in Next\.js and can not be used as/ ) }) }) diff --git a/test/integration/errors-on-output-to-static/pages/index.js b/test/integration/errors-on-output-to-static/pages/index.js new file mode 100644 index 000000000000000..0957a987fc2f227 --- /dev/null +++ b/test/integration/errors-on-output-to-static/pages/index.js @@ -0,0 +1 @@ +export default () => 'hi' diff --git a/test/integration/errors-on-output-to-static/test/index.test.js b/test/integration/errors-on-output-to-static/test/index.test.js new file mode 100644 index 000000000000000..9ee69eba8d4101e --- /dev/null +++ b/test/integration/errors-on-output-to-static/test/index.test.js @@ -0,0 +1,28 @@ +/* eslint-env jest */ + +import path from 'path' +import fs from 'fs-extra' +import { nextBuild, nextExport } from 'next-test-utils' + +jest.setTimeout(1000 * 60 * 1) +const appDir = path.join(__dirname, '..') +const nextConfig = path.join(appDir, 'next.config.js') + +describe('Errors on output to static', () => { + it('Throws error when export out dir is static', async () => { + await fs.remove(nextConfig) + await nextBuild(appDir) + const outdir = path.join(appDir, 'static') + const results = await nextExport( + appDir, + { outdir }, + { + stdout: true, + stderr: true, + } + ) + expect(results.stdout + results.stderr).toMatch( + /The 'static' directory is reserved in Next\.js and can not be used as/ + ) + }) +})