diff --git a/.changeset/old-sides-check.md b/.changeset/old-sides-check.md
new file mode 100644
index 00000000000..a845151cc84
--- /dev/null
+++ b/.changeset/old-sides-check.md
@@ -0,0 +1,2 @@
+---
+---
diff --git a/integration/presets/longRunningApps.ts b/integration/presets/longRunningApps.ts
index b7e97d6e999..0e6ac9e13f9 100644
--- a/integration/presets/longRunningApps.ts
+++ b/integration/presets/longRunningApps.ts
@@ -36,6 +36,11 @@ export const createLongRunningApps = () => {
{ id: 'next.appRouter.withNeedsClientTrust', config: next.appRouter, env: envs.withNeedsClientTrust },
{ id: 'next.appRouter.withSharedUIVariant', config: next.appRouter, env: envs.withSharedUIVariant },
+ /**
+ * NextJS apps - bundled UI
+ */
+ { id: 'next.appRouterBundledUI.withEmailCodes', config: next.appRouterBundledUI, env: envs.withEmailCodes },
+
/**
* NextJS apps - cache components
*/
diff --git a/integration/presets/next.ts b/integration/presets/next.ts
index b2073bdb5ca..ae212742525 100644
--- a/integration/presets/next.ts
+++ b/integration/presets/next.ts
@@ -36,6 +36,21 @@ const appRouterAPWithClerkNextV6 = appRouterQuickstartV6
.setName('next-app-router-ap-clerk-next-v6')
.addDependency('@clerk/nextjs', '6');
+const appRouterBundledUI = applicationConfig()
+ .setName('next-app-router-bundled-ui')
+ .useTemplate(templates['next-app-router-bundled-ui'])
+ .setEnvFormatter('public', key => `NEXT_PUBLIC_${key}`)
+ .addScript('setup', constants.E2E_NPM_FORCE ? 'pnpm install --force' : 'pnpm install')
+ .addScript('dev', 'pnpm dev')
+ .addScript('build', 'pnpm build')
+ .addScript('serve', 'pnpm start')
+ .addDependency('next', constants.E2E_NEXTJS_VERSION)
+ .addDependency('react', constants.E2E_REACT_VERSION)
+ .addDependency('react-dom', constants.E2E_REACT_DOM_VERSION)
+ .addDependency('@clerk/nextjs', constants.E2E_CLERK_JS_VERSION || linkPackage('nextjs'))
+ .addDependency('@clerk/shared', linkPackage('shared'))
+ .addDependency('@clerk/ui', constants.E2E_CLERK_UI_VERSION || linkPackage('ui'));
+
const cacheComponents = applicationConfig()
.setName('next-cache-components')
.useTemplate(templates['next-cache-components'])
@@ -54,5 +69,6 @@ export const next = {
appRouterAPWithClerkNextLatest,
appRouterAPWithClerkNextV6,
appRouterQuickstartV6,
+ appRouterBundledUI,
cacheComponents,
} as const;
diff --git a/integration/templates/index.ts b/integration/templates/index.ts
index 4e439b6d18e..b1ed93218a9 100644
--- a/integration/templates/index.ts
+++ b/integration/templates/index.ts
@@ -7,6 +7,7 @@ export const templates = {
'next-app-router': resolve(__dirname, './next-app-router'),
'next-cache-components': resolve(__dirname, './next-cache-components'),
'next-app-router-quickstart': resolve(__dirname, './next-app-router-quickstart'),
+ 'next-app-router-bundled-ui': resolve(__dirname, './next-app-router-bundled-ui'),
'next-app-router-quickstart-v6': resolve(__dirname, './next-app-router-quickstart-v6'),
'react-cra': resolve(__dirname, './react-cra'),
'react-vite': resolve(__dirname, './react-vite'),
diff --git a/integration/templates/next-app-router-bundled-ui/.gitignore b/integration/templates/next-app-router-bundled-ui/.gitignore
new file mode 100644
index 00000000000..8f322f0d8f4
--- /dev/null
+++ b/integration/templates/next-app-router-bundled-ui/.gitignore
@@ -0,0 +1,35 @@
+# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
+
+# dependencies
+/node_modules
+/.pnp
+.pnp.js
+
+# testing
+/coverage
+
+# next.js
+/.next/
+/out/
+
+# production
+/build
+
+# misc
+.DS_Store
+*.pem
+
+# debug
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+
+# local env files
+.env*.local
+
+# vercel
+.vercel
+
+# typescript
+*.tsbuildinfo
+next-env.d.ts
diff --git a/integration/templates/next-app-router-bundled-ui/next.config.js b/integration/templates/next-app-router-bundled-ui/next.config.js
new file mode 100644
index 00000000000..658404ac690
--- /dev/null
+++ b/integration/templates/next-app-router-bundled-ui/next.config.js
@@ -0,0 +1,4 @@
+/** @type {import('next').NextConfig} */
+const nextConfig = {};
+
+module.exports = nextConfig;
diff --git a/integration/templates/next-app-router-bundled-ui/package.json b/integration/templates/next-app-router-bundled-ui/package.json
new file mode 100644
index 00000000000..17a85e0571f
--- /dev/null
+++ b/integration/templates/next-app-router-bundled-ui/package.json
@@ -0,0 +1,23 @@
+{
+ "name": "next-app-router-bundled-ui",
+ "version": "0.1.0",
+ "private": true,
+ "scripts": {
+ "build": "next build",
+ "dev": "next dev",
+ "lint": "next lint",
+ "start": "next start"
+ },
+ "dependencies": {
+ "@types/node": "^20.12.12",
+ "@types/react": "19.2.14",
+ "@types/react-dom": "19.2.3",
+ "next": "^15.0.1",
+ "react": "19.2.4",
+ "react-dom": "19.2.4",
+ "typescript": "^5.7.3"
+ },
+ "engines": {
+ "node": ">=20.9.0"
+ }
+}
diff --git a/integration/templates/next-app-router-bundled-ui/public/next.svg b/integration/templates/next-app-router-bundled-ui/public/next.svg
new file mode 100644
index 00000000000..5174b28c565
--- /dev/null
+++ b/integration/templates/next-app-router-bundled-ui/public/next.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/integration/templates/next-app-router-bundled-ui/public/vercel.svg b/integration/templates/next-app-router-bundled-ui/public/vercel.svg
new file mode 100644
index 00000000000..d2f84222734
--- /dev/null
+++ b/integration/templates/next-app-router-bundled-ui/public/vercel.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/integration/templates/next-app-router-bundled-ui/src/app/favicon.ico b/integration/templates/next-app-router-bundled-ui/src/app/favicon.ico
new file mode 100644
index 00000000000..718d6fea483
Binary files /dev/null and b/integration/templates/next-app-router-bundled-ui/src/app/favicon.ico differ
diff --git a/integration/templates/next-app-router-bundled-ui/src/app/globals.css b/integration/templates/next-app-router-bundled-ui/src/app/globals.css
new file mode 100644
index 00000000000..760b257c8cc
--- /dev/null
+++ b/integration/templates/next-app-router-bundled-ui/src/app/globals.css
@@ -0,0 +1,78 @@
+:root {
+ --max-width: 1100px;
+ --border-radius: 12px;
+ --font-mono:
+ ui-monospace, Menlo, Monaco, 'Cascadia Mono', 'Segoe UI Mono', 'Roboto Mono', 'Oxygen Mono', 'Ubuntu Monospace',
+ 'Source Code Pro', 'Fira Mono', 'Droid Sans Mono', 'Courier New', monospace;
+
+ --foreground-rgb: 0, 0, 0;
+ --background-start-rgb: 214, 219, 220;
+ --background-end-rgb: 255, 255, 255;
+
+ --primary-glow: conic-gradient(
+ from 180deg at 50% 50%,
+ #16abff33 0deg,
+ #0885ff33 55deg,
+ #54d6ff33 120deg,
+ #0071ff33 160deg,
+ transparent 360deg
+ );
+ --secondary-glow: radial-gradient(rgba(255, 255, 255, 1), rgba(255, 255, 255, 0));
+
+ --tile-start-rgb: 239, 245, 249;
+ --tile-end-rgb: 228, 232, 233;
+ --tile-border: conic-gradient(#00000080, #00000040, #00000030, #00000020, #00000010, #00000010, #00000080);
+
+ --callout-rgb: 238, 240, 241;
+ --callout-border-rgb: 172, 175, 176;
+ --card-rgb: 180, 185, 188;
+ --card-border-rgb: 131, 134, 135;
+}
+
+@media (prefers-color-scheme: dark) {
+ :root {
+ --foreground-rgb: 255, 255, 255;
+ --background-start-rgb: 0, 0, 0;
+ --background-end-rgb: 0, 0, 0;
+
+ --primary-glow: radial-gradient(rgba(1, 65, 255, 0.4), rgba(1, 65, 255, 0));
+ --secondary-glow: linear-gradient(to bottom right, rgba(1, 65, 255, 0), rgba(1, 65, 255, 0), rgba(1, 65, 255, 0.3));
+
+ --tile-start-rgb: 2, 13, 46;
+ --tile-end-rgb: 2, 5, 19;
+ --tile-border: conic-gradient(#ffffff80, #ffffff40, #ffffff30, #ffffff20, #ffffff10, #ffffff10, #ffffff80);
+
+ --callout-rgb: 20, 20, 20;
+ --callout-border-rgb: 108, 108, 108;
+ --card-rgb: 100, 100, 100;
+ --card-border-rgb: 200, 200, 200;
+ }
+}
+
+* {
+ box-sizing: border-box;
+ padding: 0;
+ margin: 0;
+}
+
+html,
+body {
+ max-width: 100vw;
+ overflow-x: hidden;
+}
+
+body {
+ color: rgb(var(--foreground-rgb));
+ background: linear-gradient(to bottom, transparent, rgb(var(--background-end-rgb))) rgb(var(--background-start-rgb));
+}
+
+a {
+ color: inherit;
+ text-decoration: none;
+}
+
+@media (prefers-color-scheme: dark) {
+ html {
+ color-scheme: dark;
+ }
+}
diff --git a/integration/templates/next-app-router-bundled-ui/src/app/layout.tsx b/integration/templates/next-app-router-bundled-ui/src/app/layout.tsx
new file mode 100644
index 00000000000..3cf9ae7a673
--- /dev/null
+++ b/integration/templates/next-app-router-bundled-ui/src/app/layout.tsx
@@ -0,0 +1,28 @@
+import './globals.css';
+import { Inter } from 'next/font/google';
+import { ClerkProvider } from '@clerk/nextjs';
+import { ui } from '@clerk/ui';
+
+const inter = Inter({ subsets: ['latin'] });
+
+export const metadata = {
+ title: 'Bundled UI Test App',
+};
+
+export default function RootLayout({ children }: { children: React.ReactNode }) {
+ return (
+ signed-out-state signed-in-state