diff --git a/README.md b/README.md
index 95cfe46dc..ed367cc33 100644
--- a/README.md
+++ b/README.md
@@ -14,6 +14,7 @@ Recipe | Description
[Handling errors](./examples/fundamentals__errors) | Handling thrown errors and unhandled promise rejections
[Dynamic tests](./examples/fundamentals__dynamic-tests) | Create tests dynamically from JSON data
[Dynamic tests from CSV](./examples/fundamentals__dynamic-tests-from-csv) | Create tests dynamically from CSV file
+[Dynamic tests from CSV using Webpack Preprocessor](./examples/fundamentals__dynamic-tests-from-csv-using-webpack) | Create tests dynamically from CSV file without having to specify them in cypress.config.js
[Dynamic tests from API](./examples/fundamentals__dynamic-tests-from-api) | Create tests dynamically by calling an external API
[Fixtures](./examples/fundamentals__fixtures) | Loading single or multiple fixtures
[Adding Custom Commands](./examples/fundamentals__add-custom-command) | Write your own custom commands using JavaScript with correct types for IntelliSense to work
diff --git a/examples/fundamentals__dynamic-tests-from-csv-using-webpack/README.md b/examples/fundamentals__dynamic-tests-from-csv-using-webpack/README.md
new file mode 100644
index 000000000..c645a3f77
--- /dev/null
+++ b/examples/fundamentals__dynamic-tests-from-csv-using-webpack/README.md
@@ -0,0 +1,52 @@
+# Dynamic tests from CSV data using Webpack Preprocessor
+
+There are times when you need to generate tests using external sources such as CSV. We cannot load the CSV file directly from the spec file (unless we have a special CSV file bundler), and we cannot use the `cy.readFile` command - because by then it is too late to define new tests. However we can use `@cypress/webpack-preprocessor` and `csv-loader` thus giving us the ability to load the files and best part of you dont have to specify them in the your `cypress.config.js` each time a new CSV file is to be used.
+
+We can do this by adding those two new devDependencies in `package.json` and then load them in [setupNodeEvents](cypress.config.js) function. This config object will be available in each spec file. You then can get the list of records before the tests are created, see [csv-spec-using-WebpackLoader.cy.js](./cypress/e2e/csv-spec-using-WebpackLoader.cy.js)
+
+```js
+//package.json
+"devDependencies": {
+ "@cypress/webpack-preprocessor": "^5.17.1",
+ "csv-loader": "^3.0.5"
+ }
+
+// `setupNodeEvents`
+const webpackPreprocessor = require('@cypress/webpack-preprocessor')
+const { defineConfig } = require('cypress')
+module.exports = defineConfig({
+ e2e: {
+ supportFile: false,
+ setupNodeEvents (on, config) {
+ const webpackDefaults = webpackPreprocessor.defaultOptions
+ webpackDefaults.webpackOptions.module.rules.push({
+ test: /\.csv$/,
+ loader: 'csv-loader',
+ options: {
+ dynamicTyping: true,
+ header: true,
+ skipEmptyLines: true,
+ },
+ })
+ on('file:preprocessor', webpackPreprocessor(webpackDefaults))
+ },
+ },
+})
+
+
+// cypress/e2e/csv-spec.cy.js
+const csvUsers = require('../fixtures/users.csv')
+
+csvUsers.forEach((user) => {
+ it(`has the user ${user['first name']} ${user['last name']}`, () => {
+ cy.contains('td[data-cy=userId]', user['user id'])
+ .parent('tr')
+ .within(() => {
+ cy.contains('td[data-cy=firstName]', user['first name'])
+ cy.contains('td[data-cy=lastName]', user['last name'])
+ })
+ })
+ })
+```
+
+
diff --git a/examples/fundamentals__dynamic-tests-from-csv-using-webpack/cypress.config.js b/examples/fundamentals__dynamic-tests-from-csv-using-webpack/cypress.config.js
new file mode 100644
index 000000000..1a2b84992
--- /dev/null
+++ b/examples/fundamentals__dynamic-tests-from-csv-using-webpack/cypress.config.js
@@ -0,0 +1,27 @@
+/* eslint-disable no-console */
+const webpackPreprocessor = require('@cypress/webpack-preprocessor')
+const { defineConfig } = require('cypress')
+
+// This function is called when a project is opened or re-opened (e.g. due to
+// the project's config changing)
+module.exports = defineConfig({
+ e2e: {
+ supportFile: false,
+ setupNodeEvents (on, config) {
+ // implement node event listeners here
+ const webpackDefaults = webpackPreprocessor.defaultOptions
+
+ webpackDefaults.webpackOptions.module.rules.push({
+ test: /\.csv$/,
+ loader: 'csv-loader',
+ options: {
+ dynamicTyping: true,
+ header: true,
+ skipEmptyLines: true,
+ },
+ })
+
+ on('file:preprocessor', webpackPreprocessor(webpackDefaults))
+ },
+ },
+})
diff --git a/examples/fundamentals__dynamic-tests-from-csv-using-webpack/cypress/e2e/csv-spec-using-WebpackLoader.cy.js b/examples/fundamentals__dynamic-tests-from-csv-using-webpack/cypress/e2e/csv-spec-using-WebpackLoader.cy.js
new file mode 100644
index 000000000..cd3511a16
--- /dev/null
+++ b/examples/fundamentals__dynamic-tests-from-csv-using-webpack/cypress/e2e/csv-spec-using-WebpackLoader.cy.js
@@ -0,0 +1,20 @@
+///
ID | +First name | +Last name | +
---|---|---|
101 | +Joe | +Smith | +
102 | +Mary | +Jane | +
103 | +Adam | +Peterson | +