{
  "doc": {
    "id": "app/component-testing/component-framework-configuration",
    "title": "Configure component tests",
    "description": "Configure Cypress for component testing with dev servers, bundlers, custom index files, and spec patterns.",
    "section": "app",
    "source_path": "/llm/markdown/app/component-testing/component-framework-configuration.md",
    "version": "e6c8d867c21227247f14714fb5690c7c018983c5",
    "updated_at": "2026-08-08T12:39:37.868Z",
    "headings": [
      {
        "id": "app/component-testing/component-framework-configuration#component-testing-configuration",
        "text": "Component Testing Configuration",
        "level": 1
      },
      {
        "id": "app/component-testing/component-framework-configuration#dev-server-and-bundler",
        "text": "Dev Server and Bundler",
        "level": 2
      },
      {
        "id": "app/component-testing/component-framework-configuration#how-it-works-at-runtime",
        "text": "How it works at runtime",
        "level": 3
      },
      {
        "id": "app/component-testing/component-framework-configuration#recommended-configuration",
        "text": "Recommended configuration",
        "level": 3
      },
      {
        "id": "app/component-testing/component-framework-configuration#supported-framework-and-bundler-values",
        "text": "Supported framework and bundler values",
        "level": 4
      },
      {
        "id": "app/component-testing/component-framework-configuration#automatic-bundler-configuration-detection",
        "text": "Automatic bundler configuration detection",
        "level": 3
      },
      {
        "id": "app/component-testing/component-framework-configuration#vite",
        "text": "Vite",
        "level": 4
      },
      {
        "id": "app/component-testing/component-framework-configuration#webpack",
        "text": "Webpack",
        "level": 4
      },
      {
        "id": "app/component-testing/component-framework-configuration#overriding-bundler-configuration",
        "text": "Overriding bundler configuration",
        "level": 3
      },
      {
        "id": "app/component-testing/component-framework-configuration#vite-overrides",
        "text": "Vite overrides",
        "level": 4
      },
      {
        "id": "app/component-testing/component-framework-configuration#webpack-overrides",
        "text": "Webpack overrides",
        "level": 4
      },
      {
        "id": "app/component-testing/component-framework-configuration#resolving-import-path-aliases",
        "text": "Resolving import path aliases",
        "level": 3
      },
      {
        "id": "app/component-testing/component-framework-configuration#meta-frameworks-that-own-the-bundler-config",
        "text": "Meta-frameworks that own the bundler config",
        "level": 4
      },
      {
        "id": "app/component-testing/component-framework-configuration#aliases-defined-in-tsconfig-json",
        "text": "Aliases defined in tsconfig.json",
        "level": 4
      },
      {
        "id": "app/component-testing/component-framework-configuration#function-syntax-advanced",
        "text": "Function syntax (advanced)",
        "level": 3
      },
      {
        "id": "app/component-testing/component-framework-configuration#devserverpublicpathroute",
        "text": "devServerPublicPathRoute",
        "level": 3
      },
      {
        "id": "app/component-testing/component-framework-configuration#custom-index-file",
        "text": "Custom Index File",
        "level": 2
      },
      {
        "id": "app/component-testing/component-framework-configuration#fully-custom-dev-server",
        "text": "Fully Custom Dev Server",
        "level": 2
      },
      {
        "id": "app/component-testing/component-framework-configuration#spec-pattern-for-component-tests",
        "text": "Spec Pattern for Component Tests",
        "level": 2
      },
      {
        "id": "app/component-testing/component-framework-configuration#additional-config",
        "text": "Additional Config",
        "level": 2
      }
    ]
  },
  "chunks": [
    {
      "id": "app/component-testing/component-framework-configuration#dev-server-and-bundler",
      "doc_id": "app/component-testing/component-framework-configuration",
      "heading": "Dev Server and Bundler",
      "heading_level": 2,
      "content_markdown": "## Dev Server and Bundler\n\nComponent tests run inside a real browser, but unlike end-to-end tests they do not visit your production or staging app. Instead, Cypress starts a **dev server** that compiles and serves your component specs on demand.\n\nThe dev server is responsible for:\n\n1.  Compiling each spec file (and your support file) with the same transforms your app uses in development (JSX/TSX, Vue SFCs, CSS modules, path aliases, and so on).\n2.  Serving those compiled files over HTTP so Cypress App can load them.\n3.  Shutting down cleanly when you close the Cypress App or finish a test run.\n\nCypress ships with built-in dev server implementations for **Vite** and **Webpack**. You do not need to install `@cypress/vite-dev-server` or `@cypress/webpack-dev-server` separately, they are bundled with the Cypress App.\n\n### How it works at runtime\n\nWhen you open or run component tests, Cypress:\n\n1.  Reads `component.devServer` from your Cypress config file.\n2.  Starts the matching dev server (Vite or Webpack) on an available port.\n3.  Sets `baseUrl` to `http://localhost:<port>`.\n4.  Loads your component index HTML (by default `cypress/support/component-index.html`) and dynamically imports your support file (if configured) and the active spec, then hands control to Cypress.\n\n### Recommended configuration\n\nThe recommended way to configure component testing is to use the `component.devServer` object. Specify your UI framework and bundler and Cypress will wire up the correct dev server implementation for you:\n\n*   cypress.config.js\n*   cypress.config.ts\n\n```\nconst { defineConfig } = require('cypress')module.exports = defineConfig({  component: {    devServer: {      framework: 'react', // your UI framework      bundler: 'vite', // 'vite' or 'webpack'    },  },})\n```\n\n```\nimport { defineConfig } from 'cypress'export default defineConfig({  component: {    devServer: {      framework: 'react', // your UI framework      bundler: 'vite', // 'vite' or 'webpack'    },  },})\n```\n\nThis is the configuration that Cypress App scaffolds during project setup. It is all most projects need.\n\n#### Supported `framework` and `bundler` values\n\n| `framework` | Supported `bundler` values | Notes |\n| --- | --- | --- |\n| `react` | `vite`, `webpack` |  |\n| `vue` | `vite`, `webpack` |  |\n| `svelte` | `vite`, `webpack` |  |\n| `next` | `webpack` | Uses Next.js-specific Webpack presets. See [React overview — Next.js](/llm/markdown/app/component-testing/react/overview.md#Nextjs). |\n| `angular` | `webpack` | Supports an `options.projectConfig` override. See [Angular overview](/llm/markdown/app/component-testing/angular/overview.md#Options-API). |\n\nCommunity framework definitions (packages named `cypress-ct-*` or `@org/cypress-ct-*`) can also be used as the `framework` value when paired with a supported bundler. See [Custom Frameworks](/llm/markdown/app/component-testing/custom-frameworks.md).\n\n### Automatic bundler configuration detection\n\nWhen you use the `component.devServer` object, Cypress tries to reuse the same bundler configuration you already use to develop your app. You usually do **not** need to duplicate your entire Vite or Webpack config in your Cypress config file.\n\n#### Vite\n\nIf you omit `viteConfig`, Cypress searches upward from your project root for a `vite.config.ts|js|mjs|cjs|mts|cts` file.\n\nWhen a config file is found, Cypress loads it and merges in Cypress-specific settings (plugins, public path, spec entries, and file-system allow rules).\n\nIf no config file is found, Cypress shows an error asking you to add a `vite.config` file or pass a `viteConfig` option explicitly.\n\n#### Webpack\n\nIf you omit `webpackConfig`, Cypress searches upward from your project root for a `webpack.config.ts|js|mjs|cjs|mts|cts` file.\n\nFor meta-frameworks like **Next.js** and **Angular**, Cypress applies framework-specific presets before merging your config. For React, Vue, and Svelte, Cypress merges your detected Webpack config with a Cypress-specific overlay.\n\nIf no Webpack config can be detected and no framework preset applies, Cypress shows an error asking you to add a `webpack.config` file or pass a `webpackConfig` option explicitly.\n\n### Overriding bundler configuration\n\nPass `viteConfig` or `webpackConfig` when you need to customize what Cypress uses. For example, to add plugins, tweak aliases, or point to a config file outside the project root.\n\nBoth options accept either a config object or an async function that returns a config object.\n\n#### Vite overrides\n\n*   cypress.config.js\n*   cypress.config.ts\n\n```\nconst { defineConfig } = require('cypress')const customViteConfig = require('./vite.config.custom')module.exports = defineConfig({  component: {    devServer: {      framework: 'react',      bundler: 'vite',      // Use a specific Vite config object      viteConfig: customViteConfig,      // Or compute one at runtime      viteConfig: async () => {        const base = await import('./vite.config')        return {          ...base.default,          // test-only overrides        }      },    },  },})\n```\n\n```\nimport { defineConfig } from 'cypress'import customViteConfig from './vite.config.custom'export default defineConfig({  component: {    devServer: {      framework: 'react',      bundler: 'vite',      // Use a specific Vite config object      viteConfig: customViteConfig,      // Or compute one at runtime      viteConfig: async () => {        const base = await import('./vite.config')        return {          ...base.default,          // test-only overrides        }      },    },  },})\n```\n\n#### Webpack overrides\n\n*   cypress.config.js\n*   cypress.config.ts\n\n```\nconst { defineConfig } = require('cypress')const webpackConfig = require('./webpack.config')module.exports = defineConfig({  component: {    devServer: {      framework: 'react',      bundler: 'webpack',      webpackConfig,      webpackConfig: async () => {        const base = await import('./webpack.config')        return {          ...base.default,          // test-only overrides        }      },    },  },})\n```\n\n```\nimport { defineConfig } from 'cypress'import webpackConfig from './webpack.config'export default defineConfig({  component: {    devServer: {      framework: 'react',      bundler: 'webpack',      webpackConfig,      webpackConfig: async () => {        const base = await import('./webpack.config')        return {          ...base.default,          // test-only overrides        }      },    },  },})\n```\n\n### Resolving import path aliases\n\nIf your components import modules through path aliases (for example `import Button from '@/components/Button'` or `import { api } from '~/lib/api'`), those aliases must be resolvable by the bundler Cypress uses, otherwise the spec fails to compile with a \"module not found\" (or \"failed to resolve import\") error.\n\nCypress does **not** define any aliases of its own. It resolves them exactly the way your dev server does, using the bundler config it detects or the one you pass in:\n\n*   **Vite**: aliases come from the `resolve.alias` of the `vite.config` Cypress detects, or the `viteConfig` you pass to `devServer`.\n*   **Webpack**: aliases come from the `resolve.alias` of the `webpack.config` Cypress detects, or the `webpackConfig` you pass to `devServer`.\n\nSo if your aliases are declared in a standalone `vite.config` or `webpack.config` at (or above) your project root, Cypress picks them up automatically and no extra configuration is needed.\n\n#### Meta-frameworks that own the bundler config\n\nSome meta-frameworks (such as **Nuxt**) configure Vite internally rather than through a standalone `vite.config` file. Cypress only reads a discoverable `vite.config`/`webpack.config`. It does **not** execute `nuxt.config` (or similar) to extract the bundler settings those frameworks generate at runtime. As a result, framework-provided aliases like Nuxt's `@/` and `~/` are not visible to Cypress and must be declared explicitly via `viteConfig`:\n\n*   cypress.config.js\n*   cypress.config.ts\n\n```\nconst { defineConfig } = require('cypress')const { fileURLToPath } = require('url')module.exports = defineConfig({  component: {    devServer: {      framework: 'vue',      bundler: 'vite',      viteConfig: {        resolve: {          alias: {            '@': fileURLToPath(new URL('./', import.meta.url)),            '~': fileURLToPath(new URL('./', import.meta.url)),          },        },      },    },  },})\n```\n\n```\nimport { defineConfig } from 'cypress'import { fileURLToPath } from 'url'export default defineConfig({  component: {    devServer: {      framework: 'vue',      bundler: 'vite',      viteConfig: {        resolve: {          alias: {            '@': fileURLToPath(new URL('./', import.meta.url)),            '~': fileURLToPath(new URL('./', import.meta.url)),          },        },      },    },  },})\n```\n\nThe aliases you pass are merged with Cypress's own Vite settings, so you only need to declare the ones your components rely on. The same applies to Webpack meta-frameworks: declare the aliases under `webpackConfig.resolve.alias`.\n\n#### Aliases defined in `tsconfig.json`\n\nAliases declared only under `compilerOptions.paths` in `tsconfig.json` are a TypeScript type-checking feature. Neither Vite nor Webpack reads them when bundling, so Cypress does not resolve them either. To make `tsconfig` paths work at bundle time, add the matching plugin to the config you give Cypress:\n\n*   **Vite**: use [`vite-tsconfig-paths`](https://www.npmjs.com/package/vite-tsconfig-paths) in your `vite.config` (or in the `viteConfig` you pass to `devServer`).\n*   **Webpack**: use [`tsconfig-paths-webpack-plugin`](https://www.npmjs.com/package/tsconfig-paths-webpack-plugin) under `resolve.plugins` in your `webpack.config` (or the `webpackConfig` you pass to `devServer`).\n\nThis is the same plugin your app already needs to resolve `tsconfig` paths at build time, so reusing your existing bundler config is usually enough.\n\n### Function syntax (advanced)\n\nIf you need direct access to the dev server API — for example, to pass options that are not exposed on the object syntax — use the **function syntax** and import the dev server from the appropriate package:\n\n```\nimport { defineConfig } from 'cypress'import { devServer as viteDevServer } from '@cypress/vite-dev-server'export default defineConfig({  component: {    devServer(cypressDevServerConfig) {      return viteDevServer({        ...cypressDevServerConfig,        framework: 'react',        viteConfig: async () => {          const config = await import('./vite.config')          return config.default        },      })    },  },})\n```\n\n```\nimport { defineConfig } from 'cypress'import { devServer as webpackDevServer } from '@cypress/webpack-dev-server'export default defineConfig({  component: {    devServer(cypressDevServerConfig) {      return webpackDevServer({        ...cypressDevServerConfig,        framework: 'react',        webpackConfig: require('./webpack.config.js'),      })    },  },})\n```\n\nThe function receives a `cypressDevServerConfig` object with:\n\n| Property | Description |\n| --- | --- |\n| `specs` | Spec files Cypress is about to run |\n| `cypressConfig` | The resolved Cypress configuration |\n| `devServerEvents` | Event emitter for compile lifecycle events |\n\nIt must return (or resolve to) an object with:\n\n| Property | Description |\n| --- | --- |\n| `port` | Port the dev server is listening on |\n| `close` | Optional callback to shut the server down |\n\nYou can store additional dev server options on `component.devServerConfig` when using the function syntax. This field is passed as the second argument to your `devServer` function.\n\n### devServerPublicPathRoute\n\nThe `devServerPublicPathRoute` option controls the URL path prefix Cypress uses to load compiled specs and assets. It defaults to `/__cypress/src`.\n\nIn most projects the default works well. You may need to change it if component tests reference assets from your app's public directory and those paths must match your Vite `base` setting. For Vite 5+, set an empty string to align with Vite's default public path:\n\n*   cypress.config.js\n*   cypress.config.ts\n\n```\nconst { defineConfig } = require('cypress')module.exports = defineConfig({  component: {    devServerPublicPathRoute: '',    devServer: {      framework: 'react',      bundler: 'vite',    },  },})\n```\n\n```\nimport { defineConfig } from 'cypress'export default defineConfig({  component: {    devServerPublicPathRoute: '',    devServer: {      framework: 'react',      bundler: 'vite',    },  },})\n```\n\nUse caution when overriding this value — an incorrect public path can cause specs or assets to fail to load. See the [configuration reference](/llm/markdown/app/references/configuration.md#component) for details.\n",
      "section": "app",
      "anchors": [
        "dev-server-and-bundler"
      ],
      "path": "/llm/json/chunked/app/component-testing/component-framework-configuration.json",
      "token_estimate": 2213
    },
    {
      "id": "app/component-testing/component-framework-configuration#how-it-works-at-runtime",
      "doc_id": "app/component-testing/component-framework-configuration",
      "heading": "How it works at runtime",
      "heading_level": 3,
      "content_markdown": "### How it works at runtime\n\nWhen you open or run component tests, Cypress:\n\n1.  Reads `component.devServer` from your Cypress config file.\n2.  Starts the matching dev server (Vite or Webpack) on an available port.\n3.  Sets `baseUrl` to `http://localhost:<port>`.\n4.  Loads your component index HTML (by default `cypress/support/component-index.html`) and dynamically imports your support file (if configured) and the active spec, then hands control to Cypress.\n",
      "section": "app",
      "anchors": [
        "how-it-works-at-runtime"
      ],
      "path": "/llm/json/chunked/app/component-testing/component-framework-configuration.json",
      "token_estimate": 88
    },
    {
      "id": "app/component-testing/component-framework-configuration#recommended-configuration",
      "doc_id": "app/component-testing/component-framework-configuration",
      "heading": "Recommended configuration",
      "heading_level": 3,
      "content_markdown": "### Recommended configuration\n\nThe recommended way to configure component testing is to use the `component.devServer` object. Specify your UI framework and bundler and Cypress will wire up the correct dev server implementation for you:\n\n*   cypress.config.js\n*   cypress.config.ts\n\n```\nconst { defineConfig } = require('cypress')module.exports = defineConfig({  component: {    devServer: {      framework: 'react', // your UI framework      bundler: 'vite', // 'vite' or 'webpack'    },  },})\n```\n\n```\nimport { defineConfig } from 'cypress'export default defineConfig({  component: {    devServer: {      framework: 'react', // your UI framework      bundler: 'vite', // 'vite' or 'webpack'    },  },})\n```\n\nThis is the configuration that Cypress App scaffolds during project setup. It is all most projects need.\n\n#### Supported `framework` and `bundler` values\n\n| `framework` | Supported `bundler` values | Notes |\n| --- | --- | --- |\n| `react` | `vite`, `webpack` |  |\n| `vue` | `vite`, `webpack` |  |\n| `svelte` | `vite`, `webpack` |  |\n| `next` | `webpack` | Uses Next.js-specific Webpack presets. See [React overview — Next.js](/llm/markdown/app/component-testing/react/overview.md#Nextjs). |\n| `angular` | `webpack` | Supports an `options.projectConfig` override. See [Angular overview](/llm/markdown/app/component-testing/angular/overview.md#Options-API). |\n\nCommunity framework definitions (packages named `cypress-ct-*` or `@org/cypress-ct-*`) can also be used as the `framework` value when paired with a supported bundler. See [Custom Frameworks](/llm/markdown/app/component-testing/custom-frameworks.md).\n",
      "section": "app",
      "anchors": [
        "recommended-configuration"
      ],
      "path": "/llm/json/chunked/app/component-testing/component-framework-configuration.json",
      "token_estimate": 276
    },
    {
      "id": "app/component-testing/component-framework-configuration#supported-framework-and-bundler-values",
      "doc_id": "app/component-testing/component-framework-configuration",
      "heading": "Supported framework and bundler values",
      "heading_level": 4,
      "content_markdown": "#### Supported `framework` and `bundler` values\n\n| `framework` | Supported `bundler` values | Notes |\n| --- | --- | --- |\n| `react` | `vite`, `webpack` |  |\n| `vue` | `vite`, `webpack` |  |\n| `svelte` | `vite`, `webpack` |  |\n| `next` | `webpack` | Uses Next.js-specific Webpack presets. See [React overview — Next.js](/llm/markdown/app/component-testing/react/overview.md#Nextjs). |\n| `angular` | `webpack` | Supports an `options.projectConfig` override. See [Angular overview](/llm/markdown/app/component-testing/angular/overview.md#Options-API). |\n\nCommunity framework definitions (packages named `cypress-ct-*` or `@org/cypress-ct-*`) can also be used as the `framework` value when paired with a supported bundler. See [Custom Frameworks](/llm/markdown/app/component-testing/custom-frameworks.md).\n",
      "section": "app",
      "anchors": [
        "supported-framework-and-bundler-values"
      ],
      "path": "/llm/json/chunked/app/component-testing/component-framework-configuration.json",
      "token_estimate": 128
    },
    {
      "id": "app/component-testing/component-framework-configuration#automatic-bundler-configuration-detection",
      "doc_id": "app/component-testing/component-framework-configuration",
      "heading": "Automatic bundler configuration detection",
      "heading_level": 3,
      "content_markdown": "### Automatic bundler configuration detection\n\nWhen you use the `component.devServer` object, Cypress tries to reuse the same bundler configuration you already use to develop your app. You usually do **not** need to duplicate your entire Vite or Webpack config in your Cypress config file.\n\n#### Vite\n\nIf you omit `viteConfig`, Cypress searches upward from your project root for a `vite.config.ts|js|mjs|cjs|mts|cts` file.\n\nWhen a config file is found, Cypress loads it and merges in Cypress-specific settings (plugins, public path, spec entries, and file-system allow rules).\n\nIf no config file is found, Cypress shows an error asking you to add a `vite.config` file or pass a `viteConfig` option explicitly.\n\n#### Webpack\n\nIf you omit `webpackConfig`, Cypress searches upward from your project root for a `webpack.config.ts|js|mjs|cjs|mts|cts` file.\n\nFor meta-frameworks like **Next.js** and **Angular**, Cypress applies framework-specific presets before merging your config. For React, Vue, and Svelte, Cypress merges your detected Webpack config with a Cypress-specific overlay.\n\nIf no Webpack config can be detected and no framework preset applies, Cypress shows an error asking you to add a `webpack.config` file or pass a `webpackConfig` option explicitly.\n",
      "section": "app",
      "anchors": [
        "automatic-bundler-configuration-detection"
      ],
      "path": "/llm/json/chunked/app/component-testing/component-framework-configuration.json",
      "token_estimate": 243
    },
    {
      "id": "app/component-testing/component-framework-configuration#vite",
      "doc_id": "app/component-testing/component-framework-configuration",
      "heading": "Vite",
      "heading_level": 4,
      "content_markdown": "#### Vite\n\nIf you omit `viteConfig`, Cypress searches upward from your project root for a `vite.config.ts|js|mjs|cjs|mts|cts` file.\n\nWhen a config file is found, Cypress loads it and merges in Cypress-specific settings (plugins, public path, spec entries, and file-system allow rules).\n\nIf no config file is found, Cypress shows an error asking you to add a `vite.config` file or pass a `viteConfig` option explicitly.\n",
      "section": "app",
      "anchors": [
        "vite"
      ],
      "path": "/llm/json/chunked/app/component-testing/component-framework-configuration.json",
      "token_estimate": 84
    },
    {
      "id": "app/component-testing/component-framework-configuration#webpack",
      "doc_id": "app/component-testing/component-framework-configuration",
      "heading": "Webpack",
      "heading_level": 4,
      "content_markdown": "#### Webpack\n\nIf you omit `webpackConfig`, Cypress searches upward from your project root for a `webpack.config.ts|js|mjs|cjs|mts|cts` file.\n\nFor meta-frameworks like **Next.js** and **Angular**, Cypress applies framework-specific presets before merging your config. For React, Vue, and Svelte, Cypress merges your detected Webpack config with a Cypress-specific overlay.\n\nIf no Webpack config can be detected and no framework preset applies, Cypress shows an error asking you to add a `webpack.config` file or pass a `webpackConfig` option explicitly.\n",
      "section": "app",
      "anchors": [
        "webpack"
      ],
      "path": "/llm/json/chunked/app/component-testing/component-framework-configuration.json",
      "token_estimate": 100
    },
    {
      "id": "app/component-testing/component-framework-configuration#overriding-bundler-configuration",
      "doc_id": "app/component-testing/component-framework-configuration",
      "heading": "Overriding bundler configuration",
      "heading_level": 3,
      "content_markdown": "### Overriding bundler configuration\n\nPass `viteConfig` or `webpackConfig` when you need to customize what Cypress uses. For example, to add plugins, tweak aliases, or point to a config file outside the project root.\n\nBoth options accept either a config object or an async function that returns a config object.\n\n#### Vite overrides\n\n*   cypress.config.js\n*   cypress.config.ts\n\n```\nconst { defineConfig } = require('cypress')const customViteConfig = require('./vite.config.custom')module.exports = defineConfig({  component: {    devServer: {      framework: 'react',      bundler: 'vite',      // Use a specific Vite config object      viteConfig: customViteConfig,      // Or compute one at runtime      viteConfig: async () => {        const base = await import('./vite.config')        return {          ...base.default,          // test-only overrides        }      },    },  },})\n```\n\n```\nimport { defineConfig } from 'cypress'import customViteConfig from './vite.config.custom'export default defineConfig({  component: {    devServer: {      framework: 'react',      bundler: 'vite',      // Use a specific Vite config object      viteConfig: customViteConfig,      // Or compute one at runtime      viteConfig: async () => {        const base = await import('./vite.config')        return {          ...base.default,          // test-only overrides        }      },    },  },})\n```\n\n#### Webpack overrides\n\n*   cypress.config.js\n*   cypress.config.ts\n\n```\nconst { defineConfig } = require('cypress')const webpackConfig = require('./webpack.config')module.exports = defineConfig({  component: {    devServer: {      framework: 'react',      bundler: 'webpack',      webpackConfig,      webpackConfig: async () => {        const base = await import('./webpack.config')        return {          ...base.default,          // test-only overrides        }      },    },  },})\n```\n\n```\nimport { defineConfig } from 'cypress'import webpackConfig from './webpack.config'export default defineConfig({  component: {    devServer: {      framework: 'react',      bundler: 'webpack',      webpackConfig,      webpackConfig: async () => {        const base = await import('./webpack.config')        return {          ...base.default,          // test-only overrides        }      },    },  },})\n```\n",
      "section": "app",
      "anchors": [
        "overriding-bundler-configuration"
      ],
      "path": "/llm/json/chunked/app/component-testing/component-framework-configuration.json",
      "token_estimate": 345
    },
    {
      "id": "app/component-testing/component-framework-configuration#vite-overrides",
      "doc_id": "app/component-testing/component-framework-configuration",
      "heading": "Vite overrides",
      "heading_level": 4,
      "content_markdown": "#### Vite overrides\n\n*   cypress.config.js\n*   cypress.config.ts\n\n```\nconst { defineConfig } = require('cypress')const customViteConfig = require('./vite.config.custom')module.exports = defineConfig({  component: {    devServer: {      framework: 'react',      bundler: 'vite',      // Use a specific Vite config object      viteConfig: customViteConfig,      // Or compute one at runtime      viteConfig: async () => {        const base = await import('./vite.config')        return {          ...base.default,          // test-only overrides        }      },    },  },})\n```\n\n```\nimport { defineConfig } from 'cypress'import customViteConfig from './vite.config.custom'export default defineConfig({  component: {    devServer: {      framework: 'react',      bundler: 'vite',      // Use a specific Vite config object      viteConfig: customViteConfig,      // Or compute one at runtime      viteConfig: async () => {        const base = await import('./vite.config')        return {          ...base.default,          // test-only overrides        }      },    },  },})\n```\n",
      "section": "app",
      "anchors": [
        "vite-overrides"
      ],
      "path": "/llm/json/chunked/app/component-testing/component-framework-configuration.json",
      "token_estimate": 159
    },
    {
      "id": "app/component-testing/component-framework-configuration#webpack-overrides",
      "doc_id": "app/component-testing/component-framework-configuration",
      "heading": "Webpack overrides",
      "heading_level": 4,
      "content_markdown": "#### Webpack overrides\n\n*   cypress.config.js\n*   cypress.config.ts\n\n```\nconst { defineConfig } = require('cypress')const webpackConfig = require('./webpack.config')module.exports = defineConfig({  component: {    devServer: {      framework: 'react',      bundler: 'webpack',      webpackConfig,      webpackConfig: async () => {        const base = await import('./webpack.config')        return {          ...base.default,          // test-only overrides        }      },    },  },})\n```\n\n```\nimport { defineConfig } from 'cypress'import webpackConfig from './webpack.config'export default defineConfig({  component: {    devServer: {      framework: 'react',      bundler: 'webpack',      webpackConfig,      webpackConfig: async () => {        const base = await import('./webpack.config')        return {          ...base.default,          // test-only overrides        }      },    },  },})\n```\n",
      "section": "app",
      "anchors": [
        "webpack-overrides"
      ],
      "path": "/llm/json/chunked/app/component-testing/component-framework-configuration.json",
      "token_estimate": 121
    },
    {
      "id": "app/component-testing/component-framework-configuration#resolving-import-path-aliases",
      "doc_id": "app/component-testing/component-framework-configuration",
      "heading": "Resolving import path aliases",
      "heading_level": 3,
      "content_markdown": "### Resolving import path aliases\n\nIf your components import modules through path aliases (for example `import Button from '@/components/Button'` or `import { api } from '~/lib/api'`), those aliases must be resolvable by the bundler Cypress uses, otherwise the spec fails to compile with a \"module not found\" (or \"failed to resolve import\") error.\n\nCypress does **not** define any aliases of its own. It resolves them exactly the way your dev server does, using the bundler config it detects or the one you pass in:\n\n*   **Vite**: aliases come from the `resolve.alias` of the `vite.config` Cypress detects, or the `viteConfig` you pass to `devServer`.\n*   **Webpack**: aliases come from the `resolve.alias` of the `webpack.config` Cypress detects, or the `webpackConfig` you pass to `devServer`.\n\nSo if your aliases are declared in a standalone `vite.config` or `webpack.config` at (or above) your project root, Cypress picks them up automatically and no extra configuration is needed.\n\n#### Meta-frameworks that own the bundler config\n\nSome meta-frameworks (such as **Nuxt**) configure Vite internally rather than through a standalone `vite.config` file. Cypress only reads a discoverable `vite.config`/`webpack.config`. It does **not** execute `nuxt.config` (or similar) to extract the bundler settings those frameworks generate at runtime. As a result, framework-provided aliases like Nuxt's `@/` and `~/` are not visible to Cypress and must be declared explicitly via `viteConfig`:\n\n*   cypress.config.js\n*   cypress.config.ts\n\n```\nconst { defineConfig } = require('cypress')const { fileURLToPath } = require('url')module.exports = defineConfig({  component: {    devServer: {      framework: 'vue',      bundler: 'vite',      viteConfig: {        resolve: {          alias: {            '@': fileURLToPath(new URL('./', import.meta.url)),            '~': fileURLToPath(new URL('./', import.meta.url)),          },        },      },    },  },})\n```\n\n```\nimport { defineConfig } from 'cypress'import { fileURLToPath } from 'url'export default defineConfig({  component: {    devServer: {      framework: 'vue',      bundler: 'vite',      viteConfig: {        resolve: {          alias: {            '@': fileURLToPath(new URL('./', import.meta.url)),            '~': fileURLToPath(new URL('./', import.meta.url)),          },        },      },    },  },})\n```\n\nThe aliases you pass are merged with Cypress's own Vite settings, so you only need to declare the ones your components rely on. The same applies to Webpack meta-frameworks: declare the aliases under `webpackConfig.resolve.alias`.\n\n#### Aliases defined in `tsconfig.json`\n\nAliases declared only under `compilerOptions.paths` in `tsconfig.json` are a TypeScript type-checking feature. Neither Vite nor Webpack reads them when bundling, so Cypress does not resolve them either. To make `tsconfig` paths work at bundle time, add the matching plugin to the config you give Cypress:\n\n*   **Vite**: use [`vite-tsconfig-paths`](https://www.npmjs.com/package/vite-tsconfig-paths) in your `vite.config` (or in the `viteConfig` you pass to `devServer`).\n*   **Webpack**: use [`tsconfig-paths-webpack-plugin`](https://www.npmjs.com/package/tsconfig-paths-webpack-plugin) under `resolve.plugins` in your `webpack.config` (or the `webpackConfig` you pass to `devServer`).\n\nThis is the same plugin your app already needs to resolve `tsconfig` paths at build time, so reusing your existing bundler config is usually enough.\n",
      "section": "app",
      "anchors": [
        "resolving-import-path-aliases"
      ],
      "path": "/llm/json/chunked/app/component-testing/component-framework-configuration.json",
      "token_estimate": 595
    },
    {
      "id": "app/component-testing/component-framework-configuration#meta-frameworks-that-own-the-bundler-config",
      "doc_id": "app/component-testing/component-framework-configuration",
      "heading": "Meta-frameworks that own the bundler config",
      "heading_level": 4,
      "content_markdown": "#### Meta-frameworks that own the bundler config\n\nSome meta-frameworks (such as **Nuxt**) configure Vite internally rather than through a standalone `vite.config` file. Cypress only reads a discoverable `vite.config`/`webpack.config`. It does **not** execute `nuxt.config` (or similar) to extract the bundler settings those frameworks generate at runtime. As a result, framework-provided aliases like Nuxt's `@/` and `~/` are not visible to Cypress and must be declared explicitly via `viteConfig`:\n\n*   cypress.config.js\n*   cypress.config.ts\n\n```\nconst { defineConfig } = require('cypress')const { fileURLToPath } = require('url')module.exports = defineConfig({  component: {    devServer: {      framework: 'vue',      bundler: 'vite',      viteConfig: {        resolve: {          alias: {            '@': fileURLToPath(new URL('./', import.meta.url)),            '~': fileURLToPath(new URL('./', import.meta.url)),          },        },      },    },  },})\n```\n\n```\nimport { defineConfig } from 'cypress'import { fileURLToPath } from 'url'export default defineConfig({  component: {    devServer: {      framework: 'vue',      bundler: 'vite',      viteConfig: {        resolve: {          alias: {            '@': fileURLToPath(new URL('./', import.meta.url)),            '~': fileURLToPath(new URL('./', import.meta.url)),          },        },      },    },  },})\n```\n\nThe aliases you pass are merged with Cypress's own Vite settings, so you only need to declare the ones your components rely on. The same applies to Webpack meta-frameworks: declare the aliases under `webpackConfig.resolve.alias`.\n",
      "section": "app",
      "anchors": [
        "meta-frameworks-that-own-the-bundler-config"
      ],
      "path": "/llm/json/chunked/app/component-testing/component-framework-configuration.json",
      "token_estimate": 252
    },
    {
      "id": "app/component-testing/component-framework-configuration#aliases-defined-in-tsconfig-json",
      "doc_id": "app/component-testing/component-framework-configuration",
      "heading": "Aliases defined in tsconfig.json",
      "heading_level": 4,
      "content_markdown": "#### Aliases defined in `tsconfig.json`\n\nAliases declared only under `compilerOptions.paths` in `tsconfig.json` are a TypeScript type-checking feature. Neither Vite nor Webpack reads them when bundling, so Cypress does not resolve them either. To make `tsconfig` paths work at bundle time, add the matching plugin to the config you give Cypress:\n\n*   **Vite**: use [`vite-tsconfig-paths`](https://www.npmjs.com/package/vite-tsconfig-paths) in your `vite.config` (or in the `viteConfig` you pass to `devServer`).\n*   **Webpack**: use [`tsconfig-paths-webpack-plugin`](https://www.npmjs.com/package/tsconfig-paths-webpack-plugin) under `resolve.plugins` in your `webpack.config` (or the `webpackConfig` you pass to `devServer`).\n\nThis is the same plugin your app already needs to resolve `tsconfig` paths at build time, so reusing your existing bundler config is usually enough.\n",
      "section": "app",
      "anchors": [
        "aliases-defined-in-tsconfig-json"
      ],
      "path": "/llm/json/chunked/app/component-testing/component-framework-configuration.json",
      "token_estimate": 141
    },
    {
      "id": "app/component-testing/component-framework-configuration#function-syntax-advanced",
      "doc_id": "app/component-testing/component-framework-configuration",
      "heading": "Function syntax (advanced)",
      "heading_level": 3,
      "content_markdown": "### Function syntax (advanced)\n\nIf you need direct access to the dev server API — for example, to pass options that are not exposed on the object syntax — use the **function syntax** and import the dev server from the appropriate package:\n\n```\nimport { defineConfig } from 'cypress'import { devServer as viteDevServer } from '@cypress/vite-dev-server'export default defineConfig({  component: {    devServer(cypressDevServerConfig) {      return viteDevServer({        ...cypressDevServerConfig,        framework: 'react',        viteConfig: async () => {          const config = await import('./vite.config')          return config.default        },      })    },  },})\n```\n\n```\nimport { defineConfig } from 'cypress'import { devServer as webpackDevServer } from '@cypress/webpack-dev-server'export default defineConfig({  component: {    devServer(cypressDevServerConfig) {      return webpackDevServer({        ...cypressDevServerConfig,        framework: 'react',        webpackConfig: require('./webpack.config.js'),      })    },  },})\n```\n\nThe function receives a `cypressDevServerConfig` object with:\n\n| Property | Description |\n| --- | --- |\n| `specs` | Spec files Cypress is about to run |\n| `cypressConfig` | The resolved Cypress configuration |\n| `devServerEvents` | Event emitter for compile lifecycle events |\n\nIt must return (or resolve to) an object with:\n\n| Property | Description |\n| --- | --- |\n| `port` | Port the dev server is listening on |\n| `close` | Optional callback to shut the server down |\n\nYou can store additional dev server options on `component.devServerConfig` when using the function syntax. This field is passed as the second argument to your `devServer` function.\n",
      "section": "app",
      "anchors": [
        "function-syntax-advanced"
      ],
      "path": "/llm/json/chunked/app/component-testing/component-framework-configuration.json",
      "token_estimate": 304
    },
    {
      "id": "app/component-testing/component-framework-configuration#devserverpublicpathroute",
      "doc_id": "app/component-testing/component-framework-configuration",
      "heading": "devServerPublicPathRoute",
      "heading_level": 3,
      "content_markdown": "### devServerPublicPathRoute\n\nThe `devServerPublicPathRoute` option controls the URL path prefix Cypress uses to load compiled specs and assets. It defaults to `/__cypress/src`.\n\nIn most projects the default works well. You may need to change it if component tests reference assets from your app's public directory and those paths must match your Vite `base` setting. For Vite 5+, set an empty string to align with Vite's default public path:\n\n*   cypress.config.js\n*   cypress.config.ts\n\n```\nconst { defineConfig } = require('cypress')module.exports = defineConfig({  component: {    devServerPublicPathRoute: '',    devServer: {      framework: 'react',      bundler: 'vite',    },  },})\n```\n\n```\nimport { defineConfig } from 'cypress'export default defineConfig({  component: {    devServerPublicPathRoute: '',    devServer: {      framework: 'react',      bundler: 'vite',    },  },})\n```\n\nUse caution when overriding this value — an incorrect public path can cause specs or assets to fail to load. See the [configuration reference](/llm/markdown/app/references/configuration.md#component) for details.\n",
      "section": "app",
      "anchors": [
        "devserverpublicpathroute"
      ],
      "path": "/llm/json/chunked/app/component-testing/component-framework-configuration.json",
      "token_estimate": 189
    },
    {
      "id": "app/component-testing/component-framework-configuration#custom-index-file",
      "doc_id": "app/component-testing/component-framework-configuration",
      "heading": "Custom Index File",
      "heading_level": 2,
      "content_markdown": "## Custom Index File\n\nBy default, Cypress renders your components into an HTML file located at `cypress/support/component-index.html`.\n\nThe index file allows you to add in global assets, such as styles, fonts, and external scripts.\n\nYou can provide an alternative path to the file using the `indexHtmlFile` option in the [component config](/llm/markdown/app/references/configuration.md#component) options:\n\n```\n{  component: {    devServer: {      framework: 'react',      bundler: 'vite',    },    indexHtmlFile: '/custom/path/to/component-index.html',  },}\n```\n",
      "section": "app",
      "anchors": [
        "custom-index-file"
      ],
      "path": "/llm/json/chunked/app/component-testing/component-framework-configuration.json",
      "token_estimate": 89
    },
    {
      "id": "app/component-testing/component-framework-configuration#fully-custom-dev-server",
      "doc_id": "app/component-testing/component-framework-configuration",
      "heading": "Fully Custom Dev Server",
      "heading_level": 2,
      "content_markdown": "## Fully Custom Dev Server\n\nIf your project uses a bundler other than Vite or Webpack, or you need complete control over compilation, pass a custom function to `component.devServer`. This is how community integrations and preview-server setups work.\n\nThe function receives a single `DevServerOptions` argument and must return (or resolve to) a `ResolvedDevServerConfig` describing how Cypress should connect to and stop the server.\n\n```\ninterface DevServerOptions {  specs: Cypress.Spec[]  cypressConfig: Cypress.PluginConfigOptions  devServerEvents: NodeJS.EventEmitter}interface ResolvedDevServerConfig {  port: number // port the dev server is listening on  close?: (done?: () => void) => void // called by Cypress to shut the server down}\n```\n\n*   cypress.config.js\n*   cypress.config.ts\n\n```\nconst { defineConfig } = require('cypress')module.exports = defineConfig({  component: {    async devServer({ specs, cypressConfig, devServerEvents }) {      const { port, close } = await startDevServer(        specs,        cypressConfig,        devServerEvents      )      return {        port,        close,      }    },  },})\n```\n\n```\nimport { defineConfig } from 'cypress'export default defineConfig({  component: {    async devServer({      specs,      cypressConfig,      devServerEvents,    }: DevServerOptions) {      const { port, close } = await startDevServer(        specs,        cypressConfig,        devServerEvents      )      return {        port,        close,      }    },  },})\n```\n\nAny requests triggered during a test using the `devServerPublicPathRoute` as defined in the `cypressConfig` will be forwarded to your server. Cypress will trigger a request for `[devServerPublicPathRoute]/index.html` when a test is started. Your server needs to reply with the html-file referenced in `cypressConfig.indexHtmlFile` and inject a script to load the support files and the actual test.\n\n```\nfunction createServer(cypressConfig, bundleDir, port = 1234) {  const app = express()  // read kickstart script - see below for an example  const clientScript = readFileSync(    path.join(__dirname, './client-script.js'),    'utf8'  )  app.get(    cypressConfig.devServerPublicPathRoute + '/index.html',    async (_req, res) => {      // read custom index.html file      const html = await fs.readFile(        path.join(cypressConfig.repoRoot, cypressConfig.indexHtmlFile),        { encoding: 'utf8' }      )      // inject kickstart-script      const output = html.replace(        '</head>',        `<script type=\"module\">${clientScript}</script></head>`      )      res.send(output)    }  )  // you need to establish some url-to-path-mapping, if your bundler outputs  // the full directory structure you can map this one to one  app.use(cypressConfig.devServerPublicPathRoute, express.static(bundleDir))  app.listen(port)}\n```\n\nFor a real-world example, you can refer to [this loader](https://github.com/cypress-io/cypress/blob/466155c2125476374d9f9549530f67d0c6354a41/npm/vite-dev-server/src/plugins/cypress.ts#L82-L92) used by the Vite Dev Server.\n\nThe client script must retrieve information on the currently active test from the Cypress instance of the parent frame and load the corresponding bundle. If a support file is defined, it should be injected at the top of your test bundle or loaded before the test script.\n\n```\nconst CypressInstance = (window.Cypress = parent.Cypress)const devServerPublicPathRoute = CypressInstance.config(  'devServerPublicPathRoute')// `onSpecWindow` expects an array of functions that each return a dynamic// `import()`. Cypress invokes them in order, so the support file (if any)// must be added before the spec.const importsToLoad = []// If you do not bundle your support file along with the tests,// you need to add a separate import statement for the support file.const supportFilePath = CypressInstance.config('supportFile')if (supportFilePath) {  const relative = supportFilePath.replace(    CypressInstance.config('projectRoot'),    ''  )  importsToLoad.push(() => import(`${devServerPublicPathRoute}${relative}`))}// load the spec - you can extend the load function to also load cssconst { relative } = CypressInstance.specimportsToLoad.push(() => import(`${devServerPublicPathRoute}/${relative}`))// trigger loading the importsCypressInstance.onSpecWindow(window, importsToLoad)// then start the test processCypressInstance.action('app:window:before:load', window)\n```\n\nFor a more complete example you can check out the [kickstart script used in the vite-devserver.](https://github.com/cypress-io/cypress/blob/develop/npm/vite-dev-server/client/initCypressTests.js)\n\nThe `devServerEvents` event emitter is used to communicate compile lifecycle events between your server and Cypress:\n\n*   Emit `dev-server:compile:success` to notify Cypress that a build finished and tests can run.\n*   Listen for `dev-server:specs:changed` to be notified when Cypress updates the set of active spec files (e.g. when a new spec is added), so you can recompile the new entry points.\n\n```\n// signal to Cypress that compilation is donedevServerEvents.emit('dev-server:compile:success')// recompile when the active spec list changesdevServerEvents.on('dev-server:specs:changed', ({ specs }) => {  recompile(specs)})\n```\n",
      "section": "app",
      "anchors": [
        "fully-custom-dev-server"
      ],
      "path": "/llm/json/chunked/app/component-testing/component-framework-configuration.json",
      "token_estimate": 819
    },
    {
      "id": "app/component-testing/component-framework-configuration#spec-pattern-for-component-tests",
      "doc_id": "app/component-testing/component-framework-configuration",
      "heading": "Spec Pattern for Component Tests",
      "heading_level": 2,
      "content_markdown": "## Spec Pattern for Component Tests\n\nBy default, Cypress looks for spec files anywhere in your project with an extension of `.cy.js`, `.cy.jsx`, `.cy.ts`, or `.cy.tsx`. However, you can change this behavior for component tests with a custom `specPattern` value. In the following example, we've configured Cypress to look for spec files with those same extensions, but only in the `src` folder or any of its subdirectories.\n\n```\n{  component: {    devServer: {      framework: 'react',      bundler: 'vite',    },    specPattern: 'src/**/*.cy.{js,jsx,ts,tsx}',  },}\n```\n",
      "section": "app",
      "anchors": [
        "spec-pattern-for-component-tests"
      ],
      "path": "/llm/json/chunked/app/component-testing/component-framework-configuration.json",
      "token_estimate": 109
    }
  ]
}