# Cypress Documentation
# Source: https://raw.githubusercontent.com/cypress-io/cypress-documentation/main/docs/app/component-testing/component-framework-configuration.mdx
# Path: docs/app/component-testing/component-framework-configuration.mdx

---
title: 'Configure Component Tests | Cypress Documentation'
description: 'Configure Cypress for component testing with custom index files, dev servers, and spec patterns.'
sidebar_position: 30
sidebar_label: Configuration
---

<ProductHeading product="app" />

# Component Testing Configuration

:::info

##### <Icon name="question-circle" color="#4BBFD2" /> What you'll learn

- How to configure Cypress for component testing
- How to use a custom index file
- How to use a custom dev server
- How to set a custom spec pattern for component tests

:::

When you launch Cypress for the first time in a project, the app will
automatically guide you through setup and configuration. You don't need to do
anything additional to get started.

Refer to the "Framework Configuration" guide in each UI framework's overview
guide for a list of supported development servers and how they are configured.

Below are more advanced configuration options you can customize to fit your
project.

## Custom Index File

By default, Cypress renders your components into an HTML file located at
`cypress/support/component-index.html`.

The index file allows you to add in global assets, such as styles, fonts, and
external scripts.

You can provide an alternative path to the file using the `indexHtmlFile` option
in the [component config](/app/references/configuration#component) options:

```js
{
  component: {
    devServer,
    indexHtmlFile: '/custom/path/to/component-index.html'
  }
}
```

## Custom Dev Server

A custom function can be passed into the `devServer` option, which allows the
use of build systems not provided by Cypress out of the box. These can be from
the Cypress community, preview builds not included with the app, or a custom one
you create.

The function's signature takes in an object with the following properties as its
only parameter and needs to resolve an object containing the port of your dev
server and a callback to shut it down.

```ts
interface DevServerOptions {
  specs: Cypress.Spec[]
  cypressConfig: Cypress.PluginConfigOptions
  devServerEvents: NodeJS.EventEmitter
}
```

:::cypress-config-example

```ts
{
  component: {
    async devServer({specs, cypressConfig, devServerEvents}: DevServerOptions) {
      const {port, close} = await startDevServer(specs, cypressConfig, devServerEvents)

      return {
        port,
        close
      }
    },
  },
}
```

:::

Any 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.

```ts
function 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)
}
```

For 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.

The 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.

```ts
const CypressInstance = (window.Cypress = parent.Cypress)
const devServerPublicPathRoute = CypressInstance.config(
  'devServerPublicPathRoute'
)

let importPromise = Promise.resolve()

// 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'),
    ''
  )
  importPromise = importPromise.then(
    () => import(`${devServerPublicPathRoute}${relative}`)
  )
}

// load the spec - you can extend the load function to also load css
const { relative } = CypressInstance.spec
importPromise = importPromise.then(
  () => import(`${devServerPublicPathRoute}/${relative}`)
)

// trigger loading the imports
CypressInstance.onSpecWindow(window, importPromise)

// then start the test process
CypressInstance.action('app:window:before:load', window)
```

For 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)

The `devServerEvents` event emitter should be used to notify cypress about
finished builds by emitting a `dev-server:compile:success` event and to listen
for the `dev-server:specs:changed` event that will notify you about changed
entry points.

## Spec Pattern for Component Tests

By 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.

```js
{
  component: {
    specPattern: 'src/**/*.cy.{js,jsx,ts,tsx}'
  }
}
```

## Additional Config

For more information on all the available configuration options, see the
[configuration reference](/app/references/configuration).