diff --git a/e2e/next/src/next-appdir.test.ts b/e2e/next/src/next-appdir.test.ts
index 9a7b47e327..bc21eb5f3d 100644
--- a/e2e/next/src/next-appdir.test.ts
+++ b/e2e/next/src/next-appdir.test.ts
@@ -1,18 +1,11 @@
import {
cleanupProject,
- isNotWindows,
- killPorts,
newProject,
runCLI,
- runCommandUntil,
- tmpProjPath,
uniq,
updateFile,
} from '@nx/e2e/utils';
-import { getData } from 'ajv/dist/compile/validate';
-import { detectPackageManager } from 'nx/src/utils/package-manager';
import { checkApp } from './utils';
-import { p } from 'vitest/dist/types-b7007192';
describe('Next.js App Router', () => {
let proj: string;
diff --git a/e2e/next/src/next-styles.test.ts b/e2e/next/src/next-styles.test.ts
index 6e1002c7fd..5ba0700d4e 100644
--- a/e2e/next/src/next-styles.test.ts
+++ b/e2e/next/src/next-styles.test.ts
@@ -58,6 +58,19 @@ describe('Next.js apps', () => {
checkExport: false,
});
+ const scAppWithAppRouter = uniq('app');
+
+ runCLI(
+ `generate @nx/next:app ${scAppWithAppRouter} --no-interactive --style=styled-components --appDir=true`
+ );
+
+ await checkApp(scAppWithAppRouter, {
+ checkUnitTest: false, // No unit tests for app router
+ checkLint: false,
+ checkE2E: false,
+ checkExport: false,
+ });
+
const emotionApp = uniq('app');
runCLI(
diff --git a/packages/next/src/generators/application/application.spec.ts b/packages/next/src/generators/application/application.spec.ts
index ad9d253cb7..923ed2aaeb 100644
--- a/packages/next/src/generators/application/application.spec.ts
+++ b/packages/next/src/generators/application/application.spec.ts
@@ -15,7 +15,122 @@ describe('app', () => {
tree = createTreeWithEmptyWorkspace({ layout: 'apps-libs' });
});
- describe('not nested', () => {
+ it('should add a .gitkeep file to the public directory', async () => {
+ await applicationGenerator(tree, {
+ name: 'myApp',
+ style: 'css',
+ });
+
+ expect(tree.exists('apps/my-app/public/.gitkeep')).toBe(true);
+ });
+
+ it('should update tags and implicit dependencies', async () => {
+ await applicationGenerator(tree, {
+ name: 'myApp',
+ style: 'css',
+ tags: 'one,two',
+ });
+
+ const projects = Object.fromEntries(getProjects(tree));
+
+ expect(projects).toMatchObject({
+ 'my-app': {
+ tags: ['one', 'two'],
+ },
+ 'my-app-e2e': {
+ tags: [],
+ implicitDependencies: ['my-app'],
+ },
+ });
+ });
+
+ it('should extend from root tsconfig.json when no tsconfig.base.json', async () => {
+ tree.rename('tsconfig.base.json', 'tsconfig.json');
+
+ await applicationGenerator(tree, {
+ name: 'myApp',
+ style: 'css',
+ });
+
+ const tsConfig = readJson(tree, 'apps/my-app/tsconfig.json');
+ expect(tsConfig.extends).toBe('../../tsconfig.json');
+ });
+
+ describe('App Router', () => {
+ it('should generate files for app layout', async () => {
+ await applicationGenerator(tree, {
+ name: 'testApp',
+ style: 'css',
+ });
+
+ const tsConfig = readJson(tree, 'apps/test-app/tsconfig.json');
+ expect(tsConfig.include).toEqual([
+ '**/*.ts',
+ '**/*.tsx',
+ '**/*.js',
+ '**/*.jsx',
+ '../../apps/test-app/.next/types/**/*.ts',
+ '../../dist/apps/test-app/.next/types/**/*.ts',
+ 'next-env.d.ts',
+ ]);
+ expect(tree.exists('apps/test-app/pages/styles.css')).toBeFalsy();
+ expect(tree.exists('apps/test-app/app/global.css')).toBeTruthy();
+ expect(tree.exists('apps/test-app/app/page.tsx')).toBeTruthy();
+ expect(tree.exists('apps/test-app/app/layout.tsx')).toBeTruthy();
+ expect(tree.exists('apps/test-app/app/api/hello/route.ts')).toBeTruthy();
+ expect(tree.exists('apps/test-app/app/page.module.css')).toBeTruthy();
+ expect(tree.exists('apps/test-app/public/favicon.ico')).toBeTruthy();
+ });
+
+ it('should add layout types correctly for standalone apps', async () => {
+ await applicationGenerator(tree, {
+ name: 'testApp',
+ style: 'css',
+ appDir: true,
+ rootProject: true,
+ });
+
+ const tsConfig = readJson(tree, 'tsconfig.json');
+ expect(tsConfig.include).toEqual([
+ '**/*.ts',
+ '**/*.tsx',
+ '**/*.js',
+ '**/*.jsx',
+ '.next/types/**/*.ts',
+ 'dist/test-app/.next/types/**/*.ts',
+ 'next-env.d.ts',
+ ]);
+ });
+
+ it('should generate an unstyled component page', async () => {
+ await applicationGenerator(tree, {
+ name: 'testApp',
+ style: 'none',
+ appDir: true,
+ rootProject: true,
+ });
+
+ const content = tree.read('app/page.tsx').toString();
+
+ expect(content).not.toContain('import styles from');
+ expect(content).not.toContain('const StyledPage');
+ expect(content).not.toContain('className={styles.page}');
+ });
+ });
+
+ describe('Pages Router', () => {
+ it('should generate files for pages layout', async () => {
+ await applicationGenerator(tree, {
+ name: 'myApp',
+ style: 'css',
+ appDir: false,
+ });
+ expect(tree.exists('apps/my-app/tsconfig.json')).toBeTruthy();
+ expect(tree.exists('apps/my-app/pages/index.tsx')).toBeTruthy();
+ expect(tree.exists('apps/my-app/specs/index.spec.tsx')).toBeTruthy();
+ expect(tree.exists('apps/my-app/pages/index.module.css')).toBeTruthy();
+ });
+
it('should update configurations', async () => {
await applicationGenerator(tree, {
name: 'myApp',
@@ -43,70 +158,6 @@ describe('app', () => {
expect(content).not.toContain('const StyledPage');
expect(content).not.toContain('className={styles.page}');
});
-
- it('should update tags and implicit dependencies', async () => {
- await applicationGenerator(tree, {
- name: 'myApp',
- style: 'css',
- tags: 'one,two',
- });
-
- const projects = Object.fromEntries(getProjects(tree));
-
- expect(projects).toMatchObject({
- 'my-app': {
- tags: ['one', 'two'],
- },
- 'my-app-e2e': {
- tags: [],
- implicitDependencies: ['my-app'],
- },
- });
- });
-
- it('should generate files for app router layout', async () => {
- await applicationGenerator(tree, {
- name: 'myApp',
- style: 'css',
- });
- expect(tree.exists('apps/my-app/tsconfig.json')).toBeTruthy();
- expect(tree.exists('apps/my-app/app/page.tsx')).toBeTruthy();
- expect(tree.exists('apps/my-app/app/page.module.css')).toBeTruthy();
- });
-
- it('should generate files for pages layout', async () => {
- await applicationGenerator(tree, {
- name: 'myApp',
- style: 'css',
- appDir: false,
- });
- expect(tree.exists('apps/my-app/tsconfig.json')).toBeTruthy();
- expect(tree.exists('apps/my-app/pages/index.tsx')).toBeTruthy();
- expect(tree.exists('apps/my-app/specs/index.spec.tsx')).toBeTruthy();
- expect(tree.exists('apps/my-app/pages/index.module.css')).toBeTruthy();
- });
-
- it('should extend from root tsconfig.base.json', async () => {
- await applicationGenerator(tree, {
- name: 'myApp',
- style: 'css',
- });
-
- const tsConfig = readJson(tree, 'apps/my-app/tsconfig.json');
- expect(tsConfig.extends).toBe('../../tsconfig.base.json');
- });
-
- it('should extend from root tsconfig.json when no tsconfig.base.json', async () => {
- tree.rename('tsconfig.base.json', 'tsconfig.json');
-
- await applicationGenerator(tree, {
- name: 'myApp',
- style: 'css',
- });
-
- const tsConfig = readJson(tree, 'apps/my-app/tsconfig.json');
- expect(tsConfig.extends).toBe('../../tsconfig.json');
- });
});
describe('--style scss', () => {
@@ -121,6 +172,28 @@ describe('app', () => {
const indexContent = tree.read('apps/my-app/app/page.tsx', 'utf-8');
expect(indexContent).toContain(`import styles from './page.module.scss'`);
+ expect(tree.read('apps/my-app/app/layout.tsx', 'utf-8'))
+ .toMatchInlineSnapshot(`
+ "import './global.css';
+
+ export const metadata = {
+ title: 'Welcome to my-app',
+ description: 'Generated by create-nx-workspace',
+ };
+
+ export default function RootLayout({
+ children,
+ }: {
+ children: React.ReactNode;
+ }) {
+ return (
+
+
{children}
+
+ );
+ }
+ "
+ `);
});
});
@@ -136,6 +209,28 @@ describe('app', () => {
const indexContent = tree.read('apps/my-app/app/page.tsx', 'utf-8');
expect(indexContent).toContain(`import styles from './page.module.less'`);
+ expect(tree.read('apps/my-app/app/layout.tsx', 'utf-8'))
+ .toMatchInlineSnapshot(`
+ "import './global.less';
+
+ export const metadata = {
+ title: 'Welcome to my-app',
+ description: 'Generated by create-nx-workspace',
+ };
+
+ export default function RootLayout({
+ children,
+ }: {
+ children: React.ReactNode;
+ }) {
+ return (
+
+ {children}
+
+ );
+ }
+ "
+ `);
});
});
@@ -155,7 +250,7 @@ describe('app', () => {
});
describe('--style styled-components', () => {
- it('should generate scss styles', async () => {
+ it('should generate styles', async () => {
await applicationGenerator(tree, {
name: 'myApp',
style: 'styled-components',
@@ -169,11 +264,73 @@ describe('app', () => {
const indexContent = tree.read('apps/my-app/app/page.tsx', 'utf-8');
expect(indexContent).not.toContain(`import styles from './page.module`);
expect(indexContent).toContain(`import styled from 'styled-components'`);
+ expect(tree.read('apps/my-app/app/layout.tsx', 'utf-8'))
+ .toMatchInlineSnapshot(`
+ "import './global.css';
+ import { StyledComponentsRegistry } from './registry';
+
+ export const metadata = {
+ title: 'Welcome to demo2',
+ description: 'Generated by create-nx-workspace',
+ };
+
+ export default function RootLayout({
+ children,
+ }: {
+ children: React.ReactNode;
+ }) {
+ return (
+
+
+ {children}
+
+
+ );
+ }
+ "
+ `);
+ expect(tree.read('apps/my-app/app/registry.tsx', 'utf-8'))
+ .toMatchInlineSnapshot(`
+ "'use client';
+
+ import React, { useState } from 'react';
+ import { useServerInsertedHTML } from 'next/navigation';
+ import { ServerStyleSheet, StyleSheetManager } from 'styled-components';
+
+ export function StyledComponentsRegistry({
+ children,
+ }: {
+ children: React.ReactNode;
+ }) {
+ // Only create stylesheet once with lazy initial state
+ // x-ref: https://reactjs.org/docs/hooks-reference.html#lazy-initial-state
+ const [styledComponentsStyleSheet] = useState(() => new ServerStyleSheet());
+
+ useServerInsertedHTML(() => {
+ const styles = styledComponentsStyleSheet.getStyleElement();
+
+ // Types are out of date, clearTag is not defined.
+ // See: https://github.com/DefinitelyTyped/DefinitelyTyped/issues/65021
+ (styledComponentsStyleSheet.instance as any).clearTag();
+
+ return <>{styles}>;
+ });
+
+ if (typeof window !== 'undefined') return <>{children}>;
+
+ return (
+
+ {children}
+
+ );
+ }
+ "
+ `);
});
});
describe('--style @emotion/styled', () => {
- it('should generate scss styles', async () => {
+ it('should generate styles', async () => {
await applicationGenerator(tree, {
name: 'myApp',
style: '@emotion/styled',
@@ -187,6 +344,28 @@ describe('app', () => {
const indexContent = tree.read('apps/my-app/app/page.tsx', 'utf-8');
expect(indexContent).not.toContain(`import styles from './page.module`);
expect(indexContent).toContain(`import styled from '@emotion/styled'`);
+ expect(tree.read('apps/my-app/app/layout.tsx', 'utf-8'))
+ .toMatchInlineSnapshot(`
+ "import './global.css';
+
+ export const metadata = {
+ title: 'Welcome to my-app',
+ description: 'Generated by create-nx-workspace',
+ };
+
+ export default function RootLayout({
+ children,
+ }: {
+ children: React.ReactNode;
+ }) {
+ return (
+
+ {children}
+
+ );
+ }
+ "
+ `);
});
it('should add jsxImportSource in tsconfig.json', async () => {
@@ -220,6 +399,49 @@ describe('app', () => {
expect(indexContent).not.toContain(
`import styled from 'styled-components'`
);
+ expect(tree.read('apps/my-app/app/layout.tsx', 'utf-8'))
+ .toMatchInlineSnapshot(`
+ "import './global.css';
+ import { StyledJsxRegistry } from './registry';
+
+ export default function RootLayout({
+ children,
+ }: {
+ children: React.ReactNode;
+ }) {
+ return (
+
+
+ {children}
+
+
+ );
+ }
+ "
+ `);
+ expect(tree.read('apps/my-app/app/registry.tsx', 'utf-8'))
+ .toMatchInlineSnapshot(`
+ "'use client';
+
+ import React, { useState } from 'react';
+ import { useServerInsertedHTML } from 'next/navigation';
+ import { StyleRegistry, createStyleRegistry } from 'styled-jsx';
+
+ export function StyledJsxRegistry({ children }: { children: React.ReactNode }) {
+ // Only create stylesheet once with lazy initial state
+ // x-ref: https://reactjs.org/docs/hooks-reference.html#lazy-initial-state
+ const [jsxStyleRegistry] = useState(() => createStyleRegistry());
+
+ useServerInsertedHTML(() => {
+ const styles = jsxStyleRegistry.styles();
+ jsxStyleRegistry.flush();
+ return <>{styles}>;
+ });
+
+ return {children};
+ }
+ "
+ `);
});
});
@@ -245,7 +467,7 @@ describe('app', () => {
);
});
- it('should set up the nrwl next build builder', async () => {
+ it('should set up the nx next build builder', async () => {
await applicationGenerator(tree, {
name: 'my-app',
style: 'css',
@@ -260,7 +482,7 @@ describe('app', () => {
});
});
- it('should set up the nrwl next server builder', async () => {
+ it('should set up the nx next server builder', async () => {
await applicationGenerator(tree, {
name: 'my-app',
style: 'css',
@@ -283,7 +505,7 @@ describe('app', () => {
});
});
- it('should set up the nrwl next export builder', async () => {
+ it('should set up the nx next export builder', async () => {
await applicationGenerator(tree, {
name: 'my-app',
style: 'css',
@@ -448,76 +670,4 @@ describe('app', () => {
expect(tsConfigApp.exclude).not.toContain('**/*.spec.js');
});
});
-
- it('should add a .gitkeep file to the public directory', async () => {
- await applicationGenerator(tree, {
- name: 'myApp',
- style: 'css',
- });
-
- expect(tree.exists('apps/my-app/public/.gitkeep')).toBe(true);
- });
-
- describe('--appDir', () => {
- it('should generate app directory instead of pages', async () => {
- await applicationGenerator(tree, {
- name: 'testApp',
- style: 'css',
- appDir: true,
- });
-
- const tsConfig = readJson(tree, 'apps/test-app/tsconfig.json');
- expect(tsConfig.include).toEqual([
- '**/*.ts',
- '**/*.tsx',
- '**/*.js',
- '**/*.jsx',
- '../../apps/test-app/.next/types/**/*.ts',
- '../../dist/apps/test-app/.next/types/**/*.ts',
- 'next-env.d.ts',
- ]);
- expect(tree.exists('apps/test-app/pages/styles.css')).toBeFalsy();
- expect(tree.exists('apps/test-app/app/global.css')).toBeTruthy();
- expect(tree.exists('apps/test-app/app/page.tsx')).toBeTruthy();
- expect(tree.exists('apps/test-app/app/layout.tsx')).toBeTruthy();
- expect(tree.exists('apps/test-app/app/api/hello/route.ts')).toBeTruthy();
- expect(tree.exists('apps/test-app/app/page.module.css')).toBeTruthy();
- expect(tree.exists('apps/test-app/public/favicon.ico')).toBeTruthy();
- });
-
- it('should add layout types correctly for standalone apps', async () => {
- await applicationGenerator(tree, {
- name: 'testApp',
- style: 'css',
- appDir: true,
- rootProject: true,
- });
-
- const tsConfig = readJson(tree, 'tsconfig.json');
- expect(tsConfig.include).toEqual([
- '**/*.ts',
- '**/*.tsx',
- '**/*.js',
- '**/*.jsx',
- '.next/types/**/*.ts',
- 'dist/test-app/.next/types/**/*.ts',
- 'next-env.d.ts',
- ]);
- });
-
- it('should generate an unstyled component page', async () => {
- await applicationGenerator(tree, {
- name: 'testApp',
- style: 'none',
- appDir: true,
- rootProject: true,
- });
-
- const content = tree.read('app/page.tsx').toString();
-
- expect(content).not.toContain('import styles from');
- expect(content).not.toContain('const StyledPage');
- expect(content).not.toContain('className={styles.page}');
- });
- });
});
diff --git a/packages/next/src/generators/application/files/app/layout.tsx__tmpl__ b/packages/next/src/generators/application/files/app-default-layout/layout.tsx__tmpl__
similarity index 100%
rename from packages/next/src/generators/application/files/app/layout.tsx__tmpl__
rename to packages/next/src/generators/application/files/app-default-layout/layout.tsx__tmpl__
diff --git a/packages/next/src/generators/application/files/app-styled-components/layout.tsx__tmpl__ b/packages/next/src/generators/application/files/app-styled-components/layout.tsx__tmpl__
new file mode 100644
index 0000000000..38ac98e0d2
--- /dev/null
+++ b/packages/next/src/generators/application/files/app-styled-components/layout.tsx__tmpl__
@@ -0,0 +1,21 @@
+import './global.<%= stylesExt %>';
+import { StyledComponentsRegistry } from './registry';
+
+export const metadata = {
+ title: 'Welcome to demo2',
+ description: 'Generated by create-nx-workspace',
+};
+
+export default function RootLayout({
+ children,
+}: {
+ children: React.ReactNode;
+}) {
+ return (
+
+
+ {children}
+
+
+ );
+}
diff --git a/packages/next/src/generators/application/files/app-styled-components/registry.tsx__tmpl__ b/packages/next/src/generators/application/files/app-styled-components/registry.tsx__tmpl__
new file mode 100644
index 0000000000..35e10cce27
--- /dev/null
+++ b/packages/next/src/generators/application/files/app-styled-components/registry.tsx__tmpl__
@@ -0,0 +1,33 @@
+'use client';
+
+import React, { useState } from 'react';
+import { useServerInsertedHTML } from 'next/navigation';
+import { ServerStyleSheet, StyleSheetManager } from 'styled-components';
+
+export function StyledComponentsRegistry({
+ children,
+}: {
+ children: React.ReactNode;
+}) {
+ // Only create stylesheet once with lazy initial state
+ // x-ref: https://reactjs.org/docs/hooks-reference.html#lazy-initial-state
+ const [styledComponentsStyleSheet] = useState(() => new ServerStyleSheet());
+
+ useServerInsertedHTML(() => {
+ const styles = styledComponentsStyleSheet.getStyleElement();
+
+ // Types are out of date, clearTag is not defined.
+ // See: https://github.com/DefinitelyTyped/DefinitelyTyped/issues/65021
+ (styledComponentsStyleSheet.instance as any).clearTag();
+
+ return <>{styles}>;
+ });
+
+ if (typeof window !== 'undefined') return <>{children}>;
+
+ return (
+
+ {children}
+
+ );
+}
diff --git a/packages/next/src/generators/application/files/app-styled-jsx/layout.tsx__tmpl__ b/packages/next/src/generators/application/files/app-styled-jsx/layout.tsx__tmpl__
new file mode 100644
index 0000000000..791aa9f2e7
--- /dev/null
+++ b/packages/next/src/generators/application/files/app-styled-jsx/layout.tsx__tmpl__
@@ -0,0 +1,16 @@
+import './global.<%= stylesExt %>';
+import { StyledJsxRegistry } from './registry';
+
+export default function RootLayout({
+ children,
+}: {
+ children: React.ReactNode;
+}) {
+ return (
+
+
+ {children}
+
+
+ );
+}
diff --git a/packages/next/src/generators/application/files/app-styled-jsx/registry.tsx__tmpl__ b/packages/next/src/generators/application/files/app-styled-jsx/registry.tsx__tmpl__
new file mode 100644
index 0000000000..db1ed18cfa
--- /dev/null
+++ b/packages/next/src/generators/application/files/app-styled-jsx/registry.tsx__tmpl__
@@ -0,0 +1,23 @@
+'use client';
+
+import React, { useState } from 'react';
+import { useServerInsertedHTML } from 'next/navigation';
+import { StyleRegistry, createStyleRegistry } from 'styled-jsx';
+
+export function StyledJsxRegistry({
+ children,
+}: {
+ children: React.ReactNode;
+}) {
+ // Only create stylesheet once with lazy initial state
+ // x-ref: https://reactjs.org/docs/hooks-reference.html#lazy-initial-state
+ const [jsxStyleRegistry] = useState(() => createStyleRegistry());
+
+ useServerInsertedHTML(() => {
+ const styles = jsxStyleRegistry.styles();
+ jsxStyleRegistry.flush();
+ return <>{styles}>;
+ });
+
+ return {children};
+}
diff --git a/packages/next/src/generators/application/files/common/next.config.js__tmpl__ b/packages/next/src/generators/application/files/common/next.config.js__tmpl__
index eaecc4924c..76477fe502 100644
--- a/packages/next/src/generators/application/files/common/next.config.js__tmpl__
+++ b/packages/next/src/generators/application/files/common/next.config.js__tmpl__
@@ -62,6 +62,17 @@ const nextConfig = {
// See: https://github.com/gregberge/svgr
svgr: false,
},
+ <% if (style === 'styled-components') { %>
+ compiler: {
+ // For other options, see https://styled-components.com/docs/tooling#babel-plugin
+ styledComponents: true,
+ },
+ <% } else if (style === '@emotion/styled') { %>
+ compiler: {
+ // For other options, see https://nextjs.org/docs/architecture/nextjs-compiler#emotion
+ emotion: true,
+ },
+ <% } %>
};
const plugins = [
diff --git a/packages/next/src/generators/application/lib/create-application-files.ts b/packages/next/src/generators/application/lib/create-application-files.ts
index ba7d46fab7..5068cc2e9f 100644
--- a/packages/next/src/generators/application/lib/create-application-files.ts
+++ b/packages/next/src/generators/application/lib/create-application-files.ts
@@ -65,6 +65,8 @@ export function createApplicationFiles(host: Tree, options: NormalizedSchema) {
join(options.appProjectRoot, 'app'),
templateVariables
);
+
+ // RSC is not possible to unit test without extra helpers for data fetching. Leaving it to the user to figure out.
host.delete(
joinPathFragments(
options.appProjectRoot,
@@ -72,6 +74,29 @@ export function createApplicationFiles(host: Tree, options: NormalizedSchema) {
`index.spec.${options.js ? 'jsx' : 'tsx'}`
)
);
+
+ if (options.style === 'styled-components') {
+ generateFiles(
+ host,
+ join(__dirname, '../files/app-styled-components'),
+ join(options.appProjectRoot, 'app'),
+ templateVariables
+ );
+ } else if (options.style === 'styled-jsx') {
+ generateFiles(
+ host,
+ join(__dirname, '../files/app-styled-jsx'),
+ join(options.appProjectRoot, 'app'),
+ templateVariables
+ );
+ } else {
+ generateFiles(
+ host,
+ join(__dirname, '../files/app-default-layout'),
+ join(options.appProjectRoot, 'app'),
+ templateVariables
+ );
+ }
} else {
generateFiles(
host,
diff --git a/packages/next/src/generators/application/lib/show-possible-warnings.ts b/packages/next/src/generators/application/lib/show-possible-warnings.ts
index 39eb119623..c73a8e0b3f 100644
--- a/packages/next/src/generators/application/lib/show-possible-warnings.ts
+++ b/packages/next/src/generators/application/lib/show-possible-warnings.ts
@@ -4,7 +4,7 @@ import { NormalizedSchema } from './normalize-options';
export function showPossibleWarnings(tree: Tree, options: NormalizedSchema) {
if (options.style === '@emotion/styled' && options.appDir) {
logger.warn(
- `Emotion may not work with the App Router. See: https://beta.nextjs.org/docs/styling/css-in-js`
+ `Emotion may not work with the App Router. See: https://nextjs.org/docs/app/building-your-application/styling/css-in-js`
);
}
}