How to Test Next.js Components with Cypress
Set up Cypress Component Testing for Next.js, mount a React component, load its styles, and choose when an end-to-end test is the better fit.
Cypress Component Testing lets you mount an individual React component from a Next.js app in a real browser, then check its rendered output and interactions. Configure Cypress to use its Next.js development server and Webpack bundler, add the component testing support files, and mount the component with the props and dependencies it needs. Use end-to-end (E2E) tests for a complete Next.js page or behavior that depends on server-only methods such as getServerSideProps or getStaticProps.
1. Check Next.js and Cypress compatibility
Cypress’s React Component Testing documentation lists Next.js 15 and 16 as supported. The version boundary matters: as of Cypress 16.0.0, component testing requires Next.js 15.0.4 or newer, or Next.js 16. Next.js 14 is no longer supported by that Cypress release. Check the migration guide for the Cypress version installed in your project, since requirements can vary by release.
Sources: Cypress React Component Testing and the Cypress migration guide.
2. Install and configure Cypress Component Testing
If Cypress is not already in the project, install it with your package manager. For example:
npm install --save-dev cypress
Open Cypress and choose Component Testing. Its Launchpad can detect the framework and bundler and scaffold the configuration and support files. Review the generated files and make sure the component dev server is configured for Next.js and Webpack. The following is the documented configuration shape for cypress.config.js or cypress.config.ts:
import { defineConfig } from 'cypress'
export default defineConfig({
component: {
devServer: {
framework: 'next',
bundler: 'webpack',
},
},
})
Keep the file extension and module syntax consistent with the rest of your project. The component dev server compiles and serves component specs while Cypress runs; the test mounts into that browser session. It is not a test against your deployed production site.
Sources: Cypress component testing setup and component framework configuration.
3. Add a mount support file
Cypress needs a mount function for React components. The Launchpad may create this support setup for you. If it does not, configure the component support file to export Cypress’s React mount helper. A typical cypress/support/component.tsx file is:
import { mount } from 'cypress/react'
Cypress.Commands.add('mount', mount)
Ensure Cypress is configured to load the support file, and keep its path and extension aligned with your project’s TypeScript or JavaScript setup. The example gives TypeScript the command type; a JavaScript project can use the mount registration without the declaration block. If Launchpad generates an equivalent file, use that generated setup rather than registering a second, conflicting command.
4. Write a first component test
Import the component into a component spec, mount it with the props needed for the behavior under test, and assert on a stable selector or accessible output. For example, suppose stepper.tsx exports a component that accepts an initial prop and renders its count in an element marked data-cy="counter":
import { Stepper } from './stepper'
describe('Stepper', () => {
it('renders its initial count', () => {
cy.mount(<Stepper initial={2} />)
cy.get('[data-cy=counter]').should('have.text', '2')
})
})
This is an illustrative mount-and-assert pattern, adapted from Cypress’s React examples; it is not a claim about a particular project’s component API or a test run. Replace the import, props, and selector with those from your app. Cypress mounts the JSX in a real browser, so the test can inspect browser-rendered output rather than relying on a simulated DOM.
For an interactive component, assert the visible result of an action. For example, if the Stepper renders an increment button and updates the same counter:
import { Stepper } from './stepper'
describe('Stepper', () => {
it('increments when the user selects the increment button', () => {
cy.mount(<Stepper initial={2} />)
cy.get('[data-cy=increment]').click()
cy.get('[data-cy=counter]').should('have.text', '3')
})
})
Prefer selectors that are part of the component’s testing or accessibility contract. If the component depends on a provider, context, router, or other app-level setup, supply the required dependency in the test harness or wrap the component with the appropriate provider. A component test does not automatically recreate the whole Next.js runtime.
Source: Cypress React examples.
5. Load global styles in component tests
Component specs need the styles relevant to the behavior you are checking. For the documented Next.js styling setup, preserve this marker in the <head> of the component testing index HTML:
<div id="__next_css__DO_NOT_USE__"></div>
Import your app’s global stylesheet from the component support file. The exact path depends on your repository; for example:
import '../../src/index.css'
Use the stylesheet path that actually exists in your project. If global styles do not appear, check both the marker and the import path. Cypress documents that a missing marker can prevent global styles from applying or cause mounting to fail.
Source: Cypress guidance for testing component styles.
6. Choose component testing or end-to-end testing
Choose the test type based on what must execute for the behavior to be meaningful:
| Question | Component test | End-to-end test |
|---|---|---|
| What is under test? | An individual component and its behavior with supplied inputs and dependencies. | A complete page or user flow through the application. |
| Where does it run? | Mounted in a browser through Cypress’s component development server. | Against the application through its page-serving path, including server-side behavior needed by the flow. |
| Are Next.js server-only page methods executed? | No. Component tests do not execute methods such as getServerSideProps or getStaticProps. |
Use E2E coverage when the page behavior depends on its server-side path. |
| Good fit | A button, form, menu, card, or other isolated UI behavior with its required props and providers supplied. | A page that relies on server-provided props, routing, or interactions across a complete flow. |
A page that expects data from getServerSideProps or getStaticProps can receive undefined props when mounted directly as a component because those methods do not run in component testing. Cypress recommends E2E testing for Next.js pages and component testing for individual components in a Next.js app. Component tests do not validate server-rendered behavior.
Source: Cypress React Component Testing.
7. Run and maintain the tests
- Open Cypress and select Component Testing to run specs in its interactive browser, or use the component run command for CI.
- Confirm the selected testing type is Component Testing and the configured Next.js component dev server starts successfully.
- Keep specs near their components or in the component spec location used by your repository’s Cypress configuration.
- Pass explicit props and set up required providers so each spec describes its own assumptions.
- Keep component tests focused on isolated UI behavior. Add E2E coverage for server-dependent pages and complete user journeys.
Cypress compiles and serves the component specs using the configured development server, which is shut down when Cypress closes or a run finishes. As with any compiled test workflow, runtime depends on the project and setup; the cited documentation does not establish a universal speed comparison or benchmark.
8. Troubleshoot common problems
| Symptom | Likely cause | What to check |
|---|---|---|
| Cypress cannot start the component dev server. | The framework or bundler is missing or mismatched, or the installed versions fall outside the documented compatibility range. | Set framework: 'next' and bundler: 'webpack'. Check your Next.js and Cypress versions against the documentation and migration guide for the installed Cypress release. |
| Next.js 14 component testing is rejected on Cypress 16. | Cypress 16 requires Next.js 15.0.4 or newer, or Next.js 16, for component testing. | Consult the migration guide for the installed Cypress version and use a supported version combination. |
| A page spec fails because props are undefined. | The page relies on getServerSideProps, getStaticProps, or another server-side path that component testing does not execute. |
Use E2E coverage for the page, or test an extracted UI component by mounting it with explicit props. |
| Global styles are absent, or mounting fails around CSS. | The Next.js CSS injection marker is missing from the component index HTML, or the stylesheet import points to the wrong file. | Add <div id="__next_css__DO_NOT_USE__"></div> to the HTML head and verify the global stylesheet import path. |
cy.mount is unknown or its type is missing. |
The mount command was not registered or its support file is not loaded; TypeScript may also lack the custom command declaration. | Register the React mount helper once in the component support file and include the matching TypeScript declaration if the project uses TypeScript. |
| The component renders an error about missing context or a provider. | The component uses an app dependency that was not included when it was mounted. | Wrap it in the required provider or supply the dependency through the test harness. Do not assume component testing boots every part of Next.js. |
| A selector assertion is brittle or finds no element. | The test selector does not match the component markup, or it relies on presentation details that changed. | Check the rendered markup and use a stable test selector or an appropriate accessible query. |
9. Browser screenshots for visual review
A Cypress assertion checks a specific condition, such as whether a count changes after a click. A screenshot is useful when you also need a reviewable image of a browser-rendered page or component state. For a Next.js page that needs its real server-side behavior, capture the running page through its URL; a screenshot does not replace the component or E2E assertions described above.
Or skip the browser setup
ScreenshotNeo is a website screenshot API and MCP server from ScreenshotNeo. A GET request captures a URL as an image or PDF. For a screenshot of a running page, use:
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
Replace the example URL with a page you can access. See the ScreenshotNeo API documentation for options and response details. Cookie banners, popups, and chat widgets are removed before the shot. Bot checks, blank pages, and failed loads are never billed. Its MCP server lets AI agents take screenshots, and 1,000 screenshots a month are free with no card; paid plans start at $5 for 3,000.
Sign up for ScreenshotNeo and get 1,000 free screenshots a month, with no card required.
FAQ
Can I use Cypress component testing for a complete Next.js page?
You can mount React UI, but component testing does not execute Next.js server-only page methods. Use E2E tests when the page’s behavior depends on those methods or its full server-backed path.
Does Cypress component testing use a real browser?
Yes. Cypress describes component testing as mounting components directly in a real browser, using its configured component development server.
Which bundler should I configure for Next.js?
The documented Next.js component testing configuration uses Webpack, with framework: 'next' and bundler: 'webpack'.
Do I need to import global CSS into every spec?
The documented setup imports the app stylesheet from the component support file, so specs using that support setup receive the global stylesheet without repeating the import in each spec. Keep the required CSS injection marker in the component index HTML.


