diff --git a/packages/next/export/worker.ts b/packages/next/export/worker.ts
index c50547bc142ba1f..01e17ade7900661 100644
--- a/packages/next/export/worker.ts
+++ b/packages/next/export/worker.ts
@@ -273,6 +273,7 @@ export default async function exportPage({
optimizeImages,
/// @ts-ignore
optimizeCss,
+ distDir,
fontManifest: optimizeFonts
? requireFontManifest(distDir, serverless)
: null,
diff --git a/test/integration/critical-css/pages/_app.js b/test/integration/critical-css/pages/_app.js
new file mode 100644
index 000000000000000..770c366c0c3a8f5
--- /dev/null
+++ b/test/integration/critical-css/pages/_app.js
@@ -0,0 +1,6 @@
+import '../styles/styles.css'
+
+// This default export is required in a new `pages/_app.js` file.
+export default function MyApp({ Component, pageProps }) {
+ return
+}
diff --git a/test/integration/critical-css/pages/index.js b/test/integration/critical-css/pages/index.js
new file mode 100644
index 000000000000000..d3eeb9f702094ee
--- /dev/null
+++ b/test/integration/critical-css/pages/index.js
@@ -0,0 +1,9 @@
+import styles from '../styles/index.module.css'
+
+export default function Home() {
+ return (
+
+ )
+}
diff --git a/test/integration/critical-css/styles/index.module.css b/test/integration/critical-css/styles/index.module.css
new file mode 100644
index 000000000000000..54230488810a0bd
--- /dev/null
+++ b/test/integration/critical-css/styles/index.module.css
@@ -0,0 +1,15 @@
+.hello {
+ font: 15px Helvetica, Arial, sans-serif;
+ background: #eee;
+ padding: 100px;
+ text-align: center;
+ transition: 100ms ease-in background;
+}
+
+.hello:hover {
+ background: #ccc;
+}
+
+.extra-style1 {
+ background: #000;
+}
diff --git a/test/integration/critical-css/styles/styles.css b/test/integration/critical-css/styles/styles.css
new file mode 100644
index 000000000000000..54176d5d1954a1e
--- /dev/null
+++ b/test/integration/critical-css/styles/styles.css
@@ -0,0 +1,11 @@
+body {
+ font-family: 'SF Pro Text', 'SF Pro Icons', 'Helvetica Neue', 'Helvetica',
+ 'Arial', sans-serif;
+ padding: 20px 20px 60px;
+ max-width: 680px;
+ margin: 0 auto;
+}
+
+.extra-style {
+ font-size: 200%;
+}
diff --git a/test/integration/critical-css/test/index.test.js b/test/integration/critical-css/test/index.test.js
new file mode 100644
index 000000000000000..bf99ee1b7f998a4
--- /dev/null
+++ b/test/integration/critical-css/test/index.test.js
@@ -0,0 +1,67 @@
+/* eslint-env jest */
+
+import { join } from 'path'
+import {
+ killApp,
+ findPort,
+ nextStart,
+ nextBuild,
+ renderViaHTTP,
+} from 'next-test-utils'
+import fs from 'fs-extra'
+
+jest.setTimeout(1000 * 60 * 2)
+
+const appDir = join(__dirname, '../')
+const nextConfig = join(appDir, 'next.config.js')
+let appPort
+let app
+
+function runTests() {
+ it('should inline critical CSS', async () => {
+ const html = await renderViaHTTP(appPort, '/index')
+ expect(html).toMatch(
+ //
+ )
+ expect(html).toMatch(/body{font-family:SF Pro Text/)
+ })
+
+ it('should not inline non-critical css', async () => {
+ const html = await renderViaHTTP(appPort, '/index')
+ expect(html).not.toMatch(/.extra-style/)
+ })
+}
+
+describe('CSS optimization for SSR apps', () => {
+ beforeAll(async () => {
+ await fs.writeFile(
+ nextConfig,
+ `module.exports = { experimental: {optimizeCss: true} }`,
+ 'utf8'
+ )
+
+ if (fs.pathExistsSync(join(appDir, '.next'))) {
+ await fs.remove(join(appDir, '.next'))
+ }
+ await nextBuild(appDir)
+ appPort = await findPort()
+ app = await nextStart(appDir, appPort)
+ })
+ afterAll(() => killApp(app))
+ runTests()
+})
+
+describe('CSS optimization for serverless apps', () => {
+ beforeAll(async () => {
+ await fs.writeFile(
+ nextConfig,
+ `module.exports = { target: 'serverless', experimental: {optimizeCss: true} }`,
+ 'utf8'
+ )
+ await nextBuild(appDir)
+ appPort = await findPort()
+ app = await nextStart(appDir, appPort)
+ })
+ afterAll(() => killApp(app))
+ runTests()
+})