diff --git a/.gitignore b/.gitignore
index f73571726..5ca94b9cb 100644
--- a/.gitignore
+++ b/.gitignore
@@ -123,6 +123,11 @@ build
/src/data/
/src/pages/docs/
/public/algolia/sitemap.xml
-
+/public/docs-static/raw/
# Mac files
.DS_Store
+
+# Bruno
+v6
+remote
+.claude/settings.local.json
diff --git a/.mdx-validation.json b/.mdx-validation.json
new file mode 100644
index 000000000..efac83d63
--- /dev/null
+++ b/.mdx-validation.json
@@ -0,0 +1,11 @@
+{
+ "targetDir": "docs/developer-docs/6.0.x",
+ "exceptions": [
+ "get-started/welcome.mdx",
+ "get-started/install-webiny.mdx",
+ "overview/pricing.mdx",
+ "overview/features/security.mdx",
+ "tenant-manager/manage-tenants.mdx",
+ "tenant-manager/extend-tenant-model.mdx"
+ ]
+}
diff --git a/AGENTS.md b/AGENTS.md
new file mode 100644
index 000000000..3783821bd
--- /dev/null
+++ b/AGENTS.md
@@ -0,0 +1,226 @@
+# Project Instructions
+
+## Critical Project Conventions
+
+### Package Manager
+- **ALWAYS use `yarn`, NEVER use `npm`** - This project exclusively uses Yarn
+- All script execution: `yarn `
+- All package operations: `yarn add`, `yarn install`, etc.
+
+### Validation and Quality
+- **MDX/.ai.txt Pairing**: Every `.mdx` file must have a corresponding `.ai.txt` companion file
+- Run `yarn validate:mdx` to verify pairing before commits/PRs
+- Exceptions are defined in `.mdx-validation.json` (supports exact paths and glob patterns)
+- The validation script (`scripts/validate-mdx-pairing.ts`) checks bidirectionally
+
+### Project Structure
+- Documentation: `docs/developer-docs/6.0.x/`
+- Plans/design docs: `plans/` (project root)
+- Scripts: `scripts/` (TypeScript scripts executed via `tsx`)
+- Validation config: `.mdx-validation.json` (project root)
+
+## Documentation Structure
+- Documentation files live in `docs/developer-docs/6.0.x/`
+- `.mdx` files are the documentation pages
+- `.ai.txt` files are AI companion context files — read them to understand the corresponding `.mdx` file (sources, decisions, patterns, tone guidelines)
+
+### Directory Layout
+```
+docs/developer-docs/6.0.x/
+├── basic/ # Foundational patterns: DI (createAbstraction/createImplementation/createDecorator), Result pattern
+├── get-started/ # Welcome + installation guide
+├── graphql/ # GraphQL schema building with factory pattern
+├── headless-cms/ # Largest section — all CMS extensibility
+│ ├── builder/ # ModelBuilder, GroupBuilder, FieldBuilder APIs
+│ ├── event-handler/ # Entry/model/group lifecycle events
+│ ├── examples/ # Private model, single-entry model
+│ ├── ui/ # Field renderers
+│ └── use-case/ # Entry/model/group business logic
+├── overview/ # Pricing, security features
+│ └── features/
+├── tasks/ # Background task system (Runner, Context, Controller)
+└── website-builder/ # Website Builder extensibility
+ ├── event-handler/ # Page/redirect lifecycle events
+ └── use-case/ # Page/redirect business logic
+```
+
+### Key Patterns
+- Each major system follows a consistent taxonomy: **builder** (define structure) / **event-handler** (react to events) / **use-case** (custom business logic)
+- `basic/di.mdx` and `basic/result.mdx` are foundational — referenced by all other sections
+- `.ai.txt` files contain: source info, key decisions, understanding, code patterns, related docs, and tone guidelines
+- Tone is calibrated per doc type: conceptual (about), technical (reference), practical (examples)
+
+### MDX/.ai.txt Pairing Exceptions
+Current exceptions (defined in `.mdx-validation.json`):
+- `get-started/welcome.mdx` - introductory page
+- `get-started/install-webiny.mdx` - installation guide
+- `overview/pricing.mdx` - pricing overview
+- `overview/features/security.mdx` - security features
+
+## MDX Writing Conventions
+
+### Frontmatter
+Every `.mdx` file uses exactly three required fields:
+```yaml
+---
+id: <8-char-alphanumeric> # e.g., "kp9m2xnf" — short, random, lowercase
+title:
+description:
+---
+```
+Optional fields (rare, only for special pages like welcome): `pageHeader: false`, `fullWidth: true`.
+
+### Page Structure
+Every page follows this order:
+1. Frontmatter
+2. Component imports
+3. `` block with bullet list of questions
+4. `## Overview` — always the first H2, 1-3 paragraphs of prose
+5. Content sections as H2 (`##`) with H3 (`###`) subsections as needed
+6. No H1 headings in the body — the page title comes from frontmatter
+
+### Components
+Only one MDX component is used: `` from `@/components/Alert`.
+```mdx
+import {Alert} from "@/components/Alert";
+```
+
+Alert types:
+- `type="success"` — "WHAT YOU'LL LEARN" opener (every page)
+- `type="info"` — supplemental links or context (inline, overview pages)
+- `type="warning"` — important cautions (inline, overview pages)
+
+No other custom components are used (no ``, ``, etc.).
+
+### Code Blocks
+- Language tag is always specified: ` ```typescript ` or ` ```graphql `
+- **File path annotations** go after the language tag: ` ```typescript extensions/cms/group/eventHandler/create/beforeCreate.ts `
+- Use ` ```tsx ` for `webiny.config.tsx` files
+- GraphQL SDL in TypeScript uses `/* GraphQL */` tag: `builder.addTypeDefs(/* GraphQL */ \`...\`)`
+- Minimal comments in code — only for pedagogical correct/wrong comparisons using `// ✅ Correct` / `// ❌ Wrong`
+- No shell/bash code blocks
+
+### Import Paths in Code Examples
+```typescript
+// Webiny v6 API imports — use "webiny/" prefix, NOT "@webiny/"
+import { ModelFactory } from "webiny/api/cms/model";
+import { CreateEntryUseCase } from "webiny/api/cms/entry";
+import { Logger } from "webiny/api/logger";
+import { Api } from "webiny/extensions";
+import { Result } from "webiny/api";
+
+// Local file imports use .js extensions (ESM)
+import { BookRepository } from "./abstractions/BookRepository.js";
+
+// Type-only imports
+import type { CmsEntry } from "webiny/api";
+```
+
+### Text Formatting
+- Backticks for: code, class names, method names, type names, package names
+- **Bold** for key labels: `**Naming Convention:**`, `**Key Point:**`
+- Bullet lists use `-`, not numbered lists (even for sequential steps)
+- No emojis in prose
+- Inline links use standard markdown: `[text](/docs/path)`
+- "Webiny" always capitalized
+
+## Tone and Voice
+
+### General Rules
+- Concise and technical — no filler, no marketing language in developer docs
+- Direct and instructional — "Use `createAbstraction()` to create one"
+- Address the reader as "you"
+- Explain "why" briefly before showing "how"
+- Avoid "we" statements — use "The system provides/offers" instead
+- No analogies in published docs (save those for `.ai.txt` context)
+- Accessible to junior developers while remaining technically complete
+
+### Per Doc Type
+| Doc Type | Tone | Focus |
+|---|---|---|
+| `about.mdx` | Conceptual, accessible | Why and what, link to reference for how |
+| `reference.mdx` | Simple, concise, API-focused | Method signatures, minimal examples |
+| `example.mdx` | Practical, production-ready | Complete working code, copy-paste friendly |
+| `event-handler/*.mdx` | Production-ready examples | When/why to use each event, real-world scenarios |
+| `use-case/*.mdx` | Technical and complete | Full abstraction + implementation patterns |
+| `builder/*.mdx` | Technical reference | Complete method docs, practical examples per type |
+| `management.mdx` | Practical, operation-focused | Complete examples, error handling |
+| `get-started/`, `overview/` | Conversational, welcoming | High-level survey, no code |
+
+## TypeScript Code Patterns
+
+### DI Pattern (used in all implementations)
+```typescript
+import { SomeAbstraction } from "webiny/api/cms/entity";
+import { Logger } from "webiny/api/logger";
+
+// Implementation class with Impl suffix
+class SomeAbstractionImpl implements SomeAbstraction.Interface {
+ public constructor(private logger: Logger.Interface) {}
+
+ public async handle(event: SomeAbstraction.Event): Promise {
+ // implementation
+ }
+}
+
+// Factory registration — MUST be default export
+const SomeAbstractionConst = SomeAbstraction.createImplementation({
+ implementation: SomeAbstractionImpl,
+ dependencies: [Logger]
+});
+
+export default SomeAbstractionConst;
+```
+
+### Result Pattern (used in all use cases)
+```typescript
+const result = await someUseCase.execute(params);
+if (result.isFail()) {
+ // handle error — return early (guard clause)
+ return { error: result.error, data: null };
+}
+const value = result.value;
+```
+
+### Namespace Export Pattern (abstractions)
+```typescript
+export namespace MyAbstraction {
+ export type Interface = IMyAbstraction;
+ export type Params = IMyAbstractionParams;
+ export type Return = IMyAbstractionReturn;
+}
+```
+
+### Registration in webiny.config.tsx
+```tsx
+import React from "react";
+import { Api } from "webiny/extensions";
+
+export const Extensions = () => {
+ return (
+ <>
+ {/* ... all your other extensions */}
+
+ >
+ );
+};
+```
+
+### Event Handler Naming
+- Class names: `On[Resource][Before|After][Operation]Handler` (e.g., `OnPageBeforeCreateHandler`)
+- Abstraction tokens: `[Resource][Before|After][Operation]Handler` (without "On" prefix)
+- "Before" handlers receive `payload.input`; "After" handlers receive the completed entity (e.g., `payload.page`)
+
+## .ai.txt File Format
+Each `.ai.txt` companion file contains these sections:
+1. `AI Context: [Page Title] ([filename])` — header
+2. `Source of Information:` — numbered list of research sources
+3. `Key Documentation Decisions:` — editorial choices made
+4. `[Topic-specific understanding]` — detailed domain knowledge
+5. `[Code patterns/snippets]` — verified TypeScript templates
+6. `Related Documents:` — cross-references to sibling docs
+7. `Key Code Locations:` — source code paths in the Webiny repo
+8. `Tone Guidelines:` — explicit style instructions for the page
+
+### Maintenance
+- When new documentation files (`.mdx` or `.ai.txt`) are added, update the directory layout and notes in this AGENTS.md to reflect the changes.
diff --git a/CLAUDE.md b/CLAUDE.md
new file mode 100644
index 000000000..80cca7430
--- /dev/null
+++ b/CLAUDE.md
@@ -0,0 +1,3 @@
+## Startup
+- Always read `~/.claude/settings.json` at the start of every conversation.
+- Read `./AGENTS.md"
diff --git a/docs.config.ts b/docs.config.ts
index e7d77f652..4bc92e264 100644
--- a/docs.config.ts
+++ b/docs.config.ts
@@ -34,27 +34,78 @@ const linkWhitelist: string[] = [...redirects.map(r => r.source), "/forms/produc
*/
const whitelistedVersions: string[] = [];
+/**
+ * Only build versions at or above this version (e.g., "5.40.x").
+ * Set via MIN_VERSION environment variable or modify here.
+ * Set to empty string to build all versions.
+ */
+const minVersionToBuild = process.env.MIN_VERSION || "";
+
const filterByEnvironment = (version: Version) => {
// In `preview`, if there are specific versions whitelisted for deployment, those are the only ones we'll output.
if (preview && whitelistedVersions.length > 0) {
return whitelistedVersions.includes(version.getValue());
}
+ // If minVersionToBuild is set, only build versions >= minVersion or `latest`.
+ if (minVersionToBuild) {
+ if (minVersionToBuild === "latest") {
+ return version.isLatest();
+ }
+ const versionNum = parseFloat(version.getValue().replace(/[^\d.]/g, ""));
+ const minVersionNum = parseFloat(minVersionToBuild.replace(/[^\d.]/g, ""));
+ return versionNum >= minVersionNum;
+ }
+
// Build everything.
return true;
};
+const filterFilePathByVersion = (filePath: string): boolean => {
+ // Extract version from file path (e.g., /docs/developer-docs/5.40.x/... or /docs/user-guides/5.40.x/...)
+ const versionMatch = filePath.match(/\/(\d+\.\d+\.x)\//);
+
+ if (!versionMatch) {
+ // If no version in path, include the file (e.g., non-versioned docs)
+ return true;
+ }
+
+ const versionString = versionMatch[1];
+
+ // Use the same filtering logic as filterByEnvironment
+ if (preview && whitelistedVersions.length > 0) {
+ return whitelistedVersions.includes(versionString);
+ }
+
+ if (minVersionToBuild) {
+ if (minVersionToBuild === "latest") {
+ // For file paths, we can't determine if it's "latest" without more context
+ // So we'll include all versioned files when minVersionToBuild is "latest"
+ return true;
+ }
+ const versionNum = parseFloat(versionString.replace(/[^\d.]/g, ""));
+ const minVersionNum = parseFloat(minVersionToBuild.replace(/[^\d.]/g, ""));
+ return versionNum >= minVersionNum;
+ }
+
+ return true;
+};
+
const existsInDocs = (link: string) => {
return fs.pathExists(path.join(__dirname, `src/pages/${link}.js`));
};
export default {
projectRootDir: __dirname,
- cleanOutputDir: path.resolve("src/pages/docs"),
+ cleanOutputDir: [path.resolve("src/pages/docs"), path.resolve("public/raw/docs")],
sitemapOutputPath: path.resolve("public/algolia/sitemap.xml"),
- linkValidator: new LinkValidator(linkWhitelist, link => {
- return existsInDocs(link);
- }),
+ linkValidator: new LinkValidator(
+ linkWhitelist,
+ link => {
+ return existsInDocs(link);
+ },
+ filterFilePathByVersion
+ ),
documentRoots: [
/* Developer Docs */
new VersionedDocumentRootConfig({
diff --git a/docs/developer-docs/5.28.x/core-development-concepts/scaffolding/react-application.mdx b/docs/developer-docs/5.28.x/core-development-concepts/scaffolding/react-application.mdx
index 7be617254..556767825 100644
--- a/docs/developer-docs/5.28.x/core-development-concepts/scaffolding/react-application.mdx
+++ b/docs/developer-docs/5.28.x/core-development-concepts/scaffolding/react-application.mdx
@@ -227,7 +227,7 @@ import { createWatchApp, createBuildApp } from "@webiny/project-utils";
// Exports fundamental watch and build commands.
// Need to inject environment variables or link your application with an existing GraphQL API?
-// See https://www.webiny.com/docs/core-development-concepts/scaffolding/full-stack-application/webiny-config.
+// See https://www.webiny.com/docs/{version}/core-development-concepts/scaffolding/full-stack-application/webiny-config.
export default {
commands: {
async watch(options, context) {
diff --git a/docs/developer-docs/5.28.x/custom-app-tutorial/adding-user-pools/adding-user-pool-and-user-pool-domain.mdx b/docs/developer-docs/5.28.x/custom-app-tutorial/adding-user-pools/adding-user-pool-and-user-pool-domain.mdx
index 60571f521..60475728c 100644
--- a/docs/developer-docs/5.28.x/custom-app-tutorial/adding-user-pools/adding-user-pool-and-user-pool-domain.mdx
+++ b/docs/developer-docs/5.28.x/custom-app-tutorial/adding-user-pools/adding-user-pool-and-user-pool-domain.mdx
@@ -124,7 +124,7 @@ import Cloudfront from "./cloudfront";
const DEBUG = String(process.env.DEBUG);
// Enables logs forwarding.
-// https://www.webiny.com/docs/core-development-concepts/basics/watch-command#enabling-logs-forwarding
+// https://www.webiny.com/docs/{version}/core-development-concepts/basics/watch-command#enabling-logs-forwarding
const WEBINY_LOGS_FORWARD_URL = String(process.env.WEBINY_LOGS_FORWARD_URL);
export default () => {
diff --git a/docs/developer-docs/5.28.x/custom-app-tutorial/securing-graphql-api/initial-setup.mdx b/docs/developer-docs/5.28.x/custom-app-tutorial/securing-graphql-api/initial-setup.mdx
index ffdcdc68b..165e13065 100644
--- a/docs/developer-docs/5.28.x/custom-app-tutorial/securing-graphql-api/initial-setup.mdx
+++ b/docs/developer-docs/5.28.x/custom-app-tutorial/securing-graphql-api/initial-setup.mdx
@@ -73,7 +73,7 @@ import Cognito from "./cognito";
import S3 from "./s3";
// Among other things, this determines the amount of information we reveal on runtime errors.
-// https://www.webiny.com/docs/core-development-concepts/environment-variables/#debug-environment-variable
+// https://www.webiny.com/docs/{version}/core-development-concepts/environment-variables/#debug-environment-variable
const DEBUG = String(process.env.DEBUG);
// Enables logs forwarding.
diff --git a/docs/developer-docs/5.28.x/get-started/install-webiny.mdx b/docs/developer-docs/5.28.x/get-started/install-webiny.mdx
index 049740a6f..7550025bb 100644
--- a/docs/developer-docs/5.28.x/get-started/install-webiny.mdx
+++ b/docs/developer-docs/5.28.x/get-started/install-webiny.mdx
@@ -27,7 +27,7 @@ Before proceeding, make sure you have the following:
- Webiny works with both yarn versions [1 (classic)](https://yarnpkg.com/en/docs/install) and [>=2 (berry)](https://yarnpkg.com/)
- for version 1 - **1.22.0** or later is required
3. **AWS account and user credentials**
- - in order to deploy Webiny, you must have a valid [AWS account and user credentials](/docs/infrastructure/aws/configure-aws-credentials) set up on your system
+ - in order to deploy Webiny, you must have a valid [AWS account and user credentials](/docs/{version}/infrastructure/aws/configure-aws-credentials) set up on your system
## Project Setup
diff --git a/docs/developer-docs/5.28.x/infrastructure/basics/environments.mdx b/docs/developer-docs/5.28.x/infrastructure/basics/environments.mdx
index 2f31c9fd1..ba0cd3270 100644
--- a/docs/developer-docs/5.28.x/infrastructure/basics/environments.mdx
+++ b/docs/developer-docs/5.28.x/infrastructure/basics/environments.mdx
@@ -67,6 +67,6 @@ In certain cases, this might be reasonable. For example, you can reduce developm
-Depending on the environment, the **API** project application is deployed as two different sets of cloud infrastructure resources - development and production. Visit the [API Overview - Default VPC](/docs/architecture/deployment-modes/development) key topic to learn more.
+Depending on the environment, the **API** project application is deployed as two different sets of cloud infrastructure resources - development and production. Visit the [API Overview - Default VPC](/docs/{version}/architecture/deployment-modes/development) key topic to learn more.
diff --git a/docs/developer-docs/5.28.x/infrastructure/pulumi-iac/iac-with-pulumi.mdx b/docs/developer-docs/5.28.x/infrastructure/pulumi-iac/iac-with-pulumi.mdx
index eea2919a5..294945626 100644
--- a/docs/developer-docs/5.28.x/infrastructure/pulumi-iac/iac-with-pulumi.mdx
+++ b/docs/developer-docs/5.28.x/infrastructure/pulumi-iac/iac-with-pulumi.mdx
@@ -174,7 +174,7 @@ Currently, Webiny is not using the [Automation API](https://www.pulumi.com/blog/
Switching to a different infrastructure-as-code (IaC) solution would require a significant amount of work as it would involve rewriting almost all of the Webiny IaC code from scratch for a different IaC solution. **Therefore, we do not recommend it.**
However, if you want to experiment with it, you would need to create a custom CLI plugin similar to the [Webiny CLI plugin for Pulumi](https://github.com/webiny/webiny-js/tree/next/packages/cli-plugin-deploy-pulumi). This plugin is responsible for creating the deploy, destroy, watch, and other commands.
-To use your custom plugin, you would then need to import it into the `webiny.project.ts` file and remove the Pulumi plugin. The most challenging part would be transforming all of the Pulumi code into respective IaC code (i.e. transforming all Pulumi code to [CloudFormation](https://aws.amazon.com/cloudformation/), [Terraform](https://www.terraform.io/), or other IaC). You can refer to the Pulumi code to see the resources Webiny deploys and the [Cloud Infrastructure documentation](https://www.webiny.com/docs/architecture/introduction) for more information.
+To use your custom plugin, you would then need to import it into the `webiny.project.ts` file and remove the Pulumi plugin. The most challenging part would be transforming all of the Pulumi code into respective IaC code (i.e. transforming all Pulumi code to [CloudFormation](https://aws.amazon.com/cloudformation/), [Terraform](https://www.terraform.io/), or other IaC). You can refer to the Pulumi code to see the resources Webiny deploys and the [Cloud Infrastructure documentation](https://www.webiny.com/docs/{version}/architecture/introduction) for more information.
**Please keep in mind that this process will require a significant amount of effort, and it's recommended to stick with Pulumi unless your organization has strict policies that require using a different IaC solution.**
diff --git a/docs/developer-docs/5.29.x/admin-area/new-app-tutorial/scaffolding.mdx b/docs/developer-docs/5.29.x/admin-area/new-app-tutorial/scaffolding.mdx
index 693ffae43..cbf6a76ca 100644
--- a/docs/developer-docs/5.29.x/admin-area/new-app-tutorial/scaffolding.mdx
+++ b/docs/developer-docs/5.29.x/admin-area/new-app-tutorial/scaffolding.mdx
@@ -28,7 +28,7 @@ Note that, when we say GraphQL HTTP API, by default, we're referring to the one
-Learn more about the **API** project application on the cloud infrastructure level in the [Cloud Infrastructure](/docs/architecture/introduction) key topics section.
+Learn more about the **API** project application on the cloud infrastructure level in the [Cloud Infrastructure](/docs/{version}/architecture/introduction) key topics section.
diff --git a/docs/developer-docs/5.29.x/core-development-concepts/scaffolding/extend-graphql-api.mdx b/docs/developer-docs/5.29.x/core-development-concepts/scaffolding/extend-graphql-api.mdx
index 7758a334a..9c4e14ab8 100644
--- a/docs/developer-docs/5.29.x/core-development-concepts/scaffolding/extend-graphql-api.mdx
+++ b/docs/developer-docs/5.29.x/core-development-concepts/scaffolding/extend-graphql-api.mdx
@@ -223,7 +223,7 @@ You are free to create new tests in the similar fashion, or amend the existing o
Please note that, by default, the authentication and authorization logic isn't included in the generated code. In other words, all of the generated GraphQL query and mutation operations can be performed by anonymous (not logged-in) users, which is in most cases not the desired behavior.
-Luckily, with a couple of built-in utilities, this can be relatively easily added. Please check out the [existing tutorials](/docs/admin-area/new-app-tutorial/security) to learn how to implement these on your own.
+Luckily, with a couple of built-in utilities, this can be relatively easily added. Please check out the [existing tutorials](/docs/{version}/admin-area/new-app-tutorial/security) to learn how to implement these on your own.
### I need more flexibility when it comes to data querying. Can I bring in a different database, for example ElasticSearch?
diff --git a/docs/developer-docs/5.29.x/infrastructure/basics/modify-cloud-infrastructure.mdx b/docs/developer-docs/5.29.x/infrastructure/basics/modify-cloud-infrastructure.mdx
index 9b6a5c1bd..0db0f0116 100644
--- a/docs/developer-docs/5.29.x/infrastructure/basics/modify-cloud-infrastructure.mdx
+++ b/docs/developer-docs/5.29.x/infrastructure/basics/modify-cloud-infrastructure.mdx
@@ -197,7 +197,7 @@ export default createCoreApp({
### Defining Multiple Production Environments
-Upon running the [`webiny deploy`](/docs/{version}/core-development-concepts/basics/project-deployment) command, when `prod` is passed as the environment name, a Webiny project is deployed in the so-called [production deployment mode](https://www.webiny.com/docs/architecture/deployment-modes/production).
+Upon running the [`webiny deploy`](/docs/{version}/core-development-concepts/basics/project-deployment) command, when `prod` is passed as the environment name, a Webiny project is deployed in the so-called [production deployment mode](https://www.webiny.com/docs/{version}/architecture/deployment-modes/production).
On order to use the production deployment mode for environments other than `prod`, we can use the `productionEnvironments` parameter. The following example shows how we can use the production mode for the `staging` environment:
diff --git a/docs/developer-docs/5.30.x/wcp/link-a-project.mdx b/docs/developer-docs/5.30.x/wcp/link-a-project.mdx
index d6c1dcc37..b8947994c 100644
--- a/docs/developer-docs/5.30.x/wcp/link-a-project.mdx
+++ b/docs/developer-docs/5.30.x/wcp/link-a-project.mdx
@@ -84,7 +84,7 @@ And all it's left to do is to select a project from the list. **Note**: if you h

-Once you select your project, you are pretty much done, all you need to do, is to [deploy it](/docs/core-development-concepts/basics/project-deployment).
+Once you select your project, you are pretty much done, all you need to do, is to [deploy it](/docs/{version}/core-development-concepts/basics/project-deployment).
diff --git a/docs/developer-docs/5.30.x/wcp/overview.mdx b/docs/developer-docs/5.30.x/wcp/overview.mdx
index 3cadad8b2..6be36e6d8 100644
--- a/docs/developer-docs/5.30.x/wcp/overview.mdx
+++ b/docs/developer-docs/5.30.x/wcp/overview.mdx
@@ -70,7 +70,7 @@ A WCP user with an access to a specific WCP project can retrieve the license for
-To learn how to retrieve a license inside your own personal development environment, [check this guide](/docs/wcp/link-a-project#personal-development-environment).
+To learn how to retrieve a license inside your own personal development environment, [check this guide](/docs/{version}/wcp/link-a-project#personal-development-environment).
@@ -86,7 +86,7 @@ Every WCP project you create will have a CI/CD environment called `production` b
-To learn how to retrieve a license inside CI/CD environment, [check this guide](/docs/wcp/link-a-project#ci-cd-environment).
+To learn how to retrieve a license inside CI/CD environment, [check this guide](/docs/{version}/wcp/link-a-project#ci-cd-environment).
diff --git a/docs/developer-docs/5.33.x/headless-cms/extending/content-models-via-code.mdx b/docs/developer-docs/5.33.x/headless-cms/extending/content-models-via-code.mdx
index ec421b422..075f87811 100644
--- a/docs/developer-docs/5.33.x/headless-cms/extending/content-models-via-code.mdx
+++ b/docs/developer-docs/5.33.x/headless-cms/extending/content-models-via-code.mdx
@@ -41,7 +41,7 @@ In the following sections, we cover a couple of examples that show how to define
Note that we **NEVER** set the `storageId` property value as it is created automatically out of the field `id` and `type` property values.
-To find out more about the `storageId` property, and understand why it exists, please read [this](/docs/headless-cms/extending/content-models-via-code-storage-id) article.
+To find out more about the `storageId` property, and understand why it exists, please read [this](/docs/{version}/headless-cms/extending/content-models-via-code-storage-id) article.
@@ -151,7 +151,7 @@ Once plugins are registered successfully, we should be able to see the following
-With the [`webiny watch`](/docs/core-development-concepts/basics/watch-command) command up and running, the performed application code changes should be automatically rebuilt and redeployed into the cloud.
+With the [`webiny watch`](/docs/{version}/core-development-concepts/basics/watch-command) command up and running, the performed application code changes should be automatically rebuilt and redeployed into the cloud.
@@ -263,7 +263,7 @@ export default [
]
```
-With the [`webiny watch`](/docs/core-development-concepts/basics/watch-command) command up and running,
+With the [`webiny watch`](/docs/{version}/core-development-concepts/basics/watch-command) command up and running,
the performed application code changes should be automatically rebuilt and redeployed into the cloud.
And you should be able to see the following Product model.
diff --git a/docs/developer-docs/5.34.x/core-development-concepts/development/local-development.mdx b/docs/developer-docs/5.34.x/core-development-concepts/development/local-development.mdx
index 8a84b25d6..2ffeee449 100644
--- a/docs/developer-docs/5.34.x/core-development-concepts/development/local-development.mdx
+++ b/docs/developer-docs/5.34.x/core-development-concepts/development/local-development.mdx
@@ -25,7 +25,7 @@ To do local development in Webiny, the API or any infrastructure changes must be
In summary, changes made to API and infrastructure must be deployed to the cloud during local development. However, for changes made to only UI, deploying to the cloud is not necessary. Once the UI changes are finalised, these changes can be pushed to the cloud.
If you're wondering how to push changes to the cloud during development, don't worry. As previously mentioned, we have developed various CLI tools, such as the `watch` command, to make deploying changes to the cloud during development easy. The `watch` command allows you to continuously rebuild and redeploy your code, making the development process seamless.
-For detailed information, please refer to the [`watch command`](/docs/core-development-concepts/basics/watch-command) documentation.
+For detailed information, please refer to the [`watch command`](/docs/{version}/core-development-concepts/basics/watch-command) documentation.
Now let's learn more about local development with the frequently asked questions related to Webiny development.
diff --git a/docs/developer-docs/5.34.x/core-development-concepts/extending-and-customizing/customizing-the-error-output.mdx b/docs/developer-docs/5.34.x/core-development-concepts/extending-and-customizing/customizing-the-error-output.mdx
index aa1a948f1..2bc2699aa 100644
--- a/docs/developer-docs/5.34.x/core-development-concepts/extending-and-customizing/customizing-the-error-output.mdx
+++ b/docs/developer-docs/5.34.x/core-development-concepts/extending-and-customizing/customizing-the-error-output.mdx
@@ -15,7 +15,7 @@ import { Alert } from "@/components/Alert";
## Introduction
-In the `5.34.0` version we added a possibility for users to modify our `Fastify` handler instance, via the `ModifyFastifyPlugin`. To find our more on how and why we use `Fastify`, please read this [article](/docs/core-development-concepts/basics/routes-and-events).
+In the `5.34.0` version we added a possibility for users to modify our `Fastify` handler instance, via the `ModifyFastifyPlugin`. To find our more on how and why we use `Fastify`, please read this [article](/docs/{version}/core-development-concepts/basics/routes-and-events).
With the given plugin user can change and add anything to the `Fastify` instance, including the error handler.
diff --git a/docs/developer-docs/5.34.x/enterprise/use-existing-amazon-vpc.mdx b/docs/developer-docs/5.34.x/enterprise/use-existing-amazon-vpc.mdx
index 161cc6ebf..f1d506467 100644
--- a/docs/developer-docs/5.34.x/enterprise/use-existing-amazon-vpc.mdx
+++ b/docs/developer-docs/5.34.x/enterprise/use-existing-amazon-vpc.mdx
@@ -89,10 +89,10 @@ Note that, if the Webiny project is being deployed into the production environme
-Production deployment means deploying your Webiny project into `prod` environment, via the [`webiny deploy`](https://www.webiny.com/docs/core-development-concepts/basics/project-deployment) command: `yarn webiny deploy --env prod`.
+Production deployment means deploying your Webiny project into `prod` environment, via the [`webiny deploy`](https://www.webiny.com/docs/{version}/core-development-concepts/basics/project-deployment) command: `yarn webiny deploy --env prod`.
More on the development and production modes can be found here:
-[https://www.webiny.com/docs/architecture/deployment-modes/introduction](https://www.webiny.com/docs/architecture/deployment-modes/introduction)
+[https://www.webiny.com/docs/{version}/architecture/deployment-modes/introduction](https://www.webiny.com/docs/{version}/architecture/deployment-modes/introduction)
@@ -196,7 +196,7 @@ Note that for a Webiny project to work as expected, an Amazon VPC must have an [
1. **Amazon Cognito** - Webiny's application code interacts with Amazon Cognito via AWS SDK. May not be needed if the organization doesn't plan to rely on Amazon Cognito as their identity provider.
2. **Amazon CloudFront** - Webiny's application code interacts with Amazon CloudFront via AWS SDK
-3. **Webiny Control Panel (WCP)** - [Webiny Control Panel (WCP)](/docs/wcp/overview)-linked Webiny projects also frequently interact with app's public HTTP API (`api.webiny.com`)
+3. **Webiny Control Panel (WCP)** - [Webiny Control Panel (WCP)](/docs/{version}/wcpoverview)-linked Webiny projects also frequently interact with app's public HTTP API (`api.webiny.com`)
4. **Webiny's Prerendering Service** - for website performance reasons, whenever a user publishes a page created with Webiny’s Page Builder application, behind the scenes, an AWS Lambda function is triggered, which issues HTTP requests to published page’s URL (a public CloudFront URL). May not be needed if the organization doesn't plan to use the Page Builder application.
### VPC Endpoints
diff --git a/docs/developer-docs/5.34.x/headless-cms/basics/using-graphql-api-filtering.mdx b/docs/developer-docs/5.34.x/headless-cms/basics/using-graphql-api-filtering.mdx
index 91d991f79..a459ca6c1 100644
--- a/docs/developer-docs/5.34.x/headless-cms/basics/using-graphql-api-filtering.mdx
+++ b/docs/developer-docs/5.34.x/headless-cms/basics/using-graphql-api-filtering.mdx
@@ -249,4 +249,4 @@ query {
## Conditional Filtering
-The article [`Using the GraphQL API Advanced Filtering`](/docs/headless-cms/basics/using-graphql-api-advanced-filtering) will cover the conditional (advanced) filtering, where we will show you how to use the `AND` and `OR` conditionals.
+The article [`Using the GraphQL API Advanced Filtering`](/docs/{version}/headless-cms/basics/using-graphql-api-advanced-filtering) will cover the conditional (advanced) filtering, where we will show you how to use the `AND` and `OR` conditionals.
diff --git a/docs/developer-docs/5.35.x/core-development-concepts/extending-and-customizing/customizing-the-error-output.mdx b/docs/developer-docs/5.35.x/core-development-concepts/extending-and-customizing/customizing-the-error-output.mdx
index 5702c6b01..88cda93c2 100644
--- a/docs/developer-docs/5.35.x/core-development-concepts/extending-and-customizing/customizing-the-error-output.mdx
+++ b/docs/developer-docs/5.35.x/core-development-concepts/extending-and-customizing/customizing-the-error-output.mdx
@@ -15,7 +15,7 @@ import { Alert } from "@/components/Alert";
## Introduction
-In the `5.34.0` version we added a possibility for users to modify our `Fastify` handler instance, via the `ModifyFastifyPlugin`. To find our more on how and why we use `Fastify`, please read this [article](/docs/core-development-concepts/basics/routes-and-events).
+In the `5.34.0` version we added a possibility for users to modify our `Fastify` handler instance, via the `ModifyFastifyPlugin`. To find our more on how and why we use `Fastify`, please read this [article](/docs/{version}/core-development-concepts/basics/routes-and-events).
With the given plugin user can change and add anything to the `Fastify` instance, including the error handler.
diff --git a/docs/developer-docs/5.35.x/headless-cms/basics/using-graphql-api-filtering.mdx b/docs/developer-docs/5.35.x/headless-cms/basics/using-graphql-api-filtering.mdx
index 91d991f79..a459ca6c1 100644
--- a/docs/developer-docs/5.35.x/headless-cms/basics/using-graphql-api-filtering.mdx
+++ b/docs/developer-docs/5.35.x/headless-cms/basics/using-graphql-api-filtering.mdx
@@ -249,4 +249,4 @@ query {
## Conditional Filtering
-The article [`Using the GraphQL API Advanced Filtering`](/docs/headless-cms/basics/using-graphql-api-advanced-filtering) will cover the conditional (advanced) filtering, where we will show you how to use the `AND` and `OR` conditionals.
+The article [`Using the GraphQL API Advanced Filtering`](/docs/{version}/headless-cms/basics/using-graphql-api-advanced-filtering) will cover the conditional (advanced) filtering, where we will show you how to use the `AND` and `OR` conditionals.
diff --git a/docs/developer-docs/5.35.x/headless-cms/extending/content-models-via-code.mdx b/docs/developer-docs/5.35.x/headless-cms/extending/content-models-via-code.mdx
index 8c0a91954..0c00faa5c 100644
--- a/docs/developer-docs/5.35.x/headless-cms/extending/content-models-via-code.mdx
+++ b/docs/developer-docs/5.35.x/headless-cms/extending/content-models-via-code.mdx
@@ -41,7 +41,7 @@ In the following sections, we cover a couple of examples that show how to define
Note that we **NEVER** set the `storageId` property value as it is created automatically out of the field `id` and `type` property values.
-To find out more about the `storageId` property, and understand why it exists, please read [this](/docs/headless-cms/extending/content-models-via-code-storage-id) article.
+To find out more about the `storageId` property, and understand why it exists, please read [this](/docs/{version}/headless-cms/extending/content-models-via-code-storage-id) article.
@@ -151,7 +151,7 @@ Once plugins are registered successfully, we should be able to see the following
-With the [`webiny watch`](/docs/core-development-concepts/basics/watch-command) command up and running, the performed application code changes should be automatically rebuilt and redeployed into the cloud.
+With the [`webiny watch`](/docs/{version}/core-development-concepts/basics/watch-command) command up and running, the performed application code changes should be automatically rebuilt and redeployed into the cloud.
@@ -263,7 +263,7 @@ export default [
]
```
-With the [`webiny watch`](/docs/core-development-concepts/basics/watch-command) command up and running,
+With the [`webiny watch`](/docs/{version}/core-development-concepts/basics/watch-command) command up and running,
the performed application code changes should be automatically rebuilt and redeployed into the cloud.
And you should be able to see the following Product model.
@@ -388,7 +388,7 @@ renderer: {
(...)
```
-With the [`webiny watch`](/docs/core-development-concepts/basics/watch-command) command up and running,
+With the [`webiny watch`](/docs/{version}/core-development-concepts/basics/watch-command) command up and running,
the performed application code changes should be automatically rebuilt and redeployed into the cloud.
And you should be able to see the following Product Review model.
diff --git a/docs/developer-docs/5.36.x/infrastructure/basics/modify-cloud-infrastructure.mdx b/docs/developer-docs/5.36.x/infrastructure/basics/modify-cloud-infrastructure.mdx
index d1df19beb..a15073364 100644
--- a/docs/developer-docs/5.36.x/infrastructure/basics/modify-cloud-infrastructure.mdx
+++ b/docs/developer-docs/5.36.x/infrastructure/basics/modify-cloud-infrastructure.mdx
@@ -197,7 +197,7 @@ export default createCoreApp({
### Defining Multiple Production Environments
-Upon running the [`webiny deploy`](/docs/{version}/core-development-concepts/basics/project-deployment) command, when `prod` is passed as the environment name, a Webiny project is deployed in the so-called [production deployment mode](https://www.webiny.com/docs/architecture/deployment-modes/production).
+Upon running the [`webiny deploy`](/docs/{version}/core-development-concepts/basics/project-deployment) command, when `prod` is passed as the environment name, a Webiny project is deployed in the so-called [production deployment mode](https://www.webiny.com/docs/{version}/architecture/deployment-modes/production).
On order to use the production deployment mode for environments other than `prod`, we can use the `productionEnvironments` parameter. The following example shows how we can use the production mode for the `staging` environment:
diff --git a/docs/developer-docs/5.37.x/enterprise/teams.mdx b/docs/developer-docs/5.37.x/enterprise/teams.mdx
index de670a193..4d5ea3774 100644
--- a/docs/developer-docs/5.37.x/enterprise/teams.mdx
+++ b/docs/developer-docs/5.37.x/enterprise/teams.mdx
@@ -32,7 +32,7 @@ Trying to select **Custom Access** will result in an alert message being shown,
-To upgrade to **Business** tier, users [link their project](/docs/wcp/link-a-project) with [Webiny Control Panel (WCP)](/docs/wcp/overview), from where they can activate the Advanced Access Control Layer (AACL) for their project. By doing this, users will be able to define fine-grained permissions for individual Webiny apps.
+To upgrade to **Business** tier, users [link their project](/docs/{version}/wcplink-a-project) with [Webiny Control Panel (WCP)](/docs/{version}/wcpoverview), from where they can activate the Advanced Access Control Layer (AACL) for their project. By doing this, users will be able to define fine-grained permissions for individual Webiny apps.
{
Under the hood, filters are handled via a regular form component: this means we can hook into the form to set new filter values. We're using the `useBind` hook and give it a name. This `name` will become a key within the form data object, which will be passed to the GraphQL query. To unset a filter, we set `undefined`.
-You can write any filtering logic based on [Headless CMS's built-in GraphQL API filtering](/docs/headless-cms/basics/using-graphql-api-advanced-filtering).
+You can write any filtering logic based on [Headless CMS's built-in GraphQL API filtering](/docs/{version}/headless-cms/basics/using-graphql-api-advanced-filtering).
diff --git a/docs/developer-docs/5.38.x/enterprise/aacl/teams.mdx b/docs/developer-docs/5.38.x/enterprise/aacl/teams.mdx
index 049556599..30943c043 100644
--- a/docs/developer-docs/5.38.x/enterprise/aacl/teams.mdx
+++ b/docs/developer-docs/5.38.x/enterprise/aacl/teams.mdx
@@ -35,7 +35,7 @@ This feature is especially useful for larger organizations, where it's common to
## Enabling Teams and Feature Overview
-For Webiny Enterprise users, apart from [linking their Webiny project](/docs/wcp/link-a-project) with Webiny Control Panel (WCP), there are no additional steps required to enable Teams.
+For Webiny Enterprise users, apart from [linking their Webiny project](/docs/{version}/wcp/link-a-project) with Webiny Control Panel (WCP), there are no additional steps required to enable Teams.
Once linked, Teams will be automatically enabled and the module can be accessed from the main menu:
diff --git a/docs/developer-docs/5.38.x/get-started/install-webiny.mdx b/docs/developer-docs/5.38.x/get-started/install-webiny.mdx
index feabdab17..62c53c74f 100644
--- a/docs/developer-docs/5.38.x/get-started/install-webiny.mdx
+++ b/docs/developer-docs/5.38.x/get-started/install-webiny.mdx
@@ -27,7 +27,7 @@ Before proceeding, make sure you have the following:
- Webiny works with both yarn versions [1 (classic)](https://yarnpkg.com/en/docs/install) and [>=2 (berry)](https://yarnpkg.com/)
- for version 1 - **1.22.21** or later is required
3. **AWS account and user credentials**
- - in order to deploy Webiny, you must have a valid [AWS account and user credentials](/docs/infrastructure/aws/configure-aws-credentials) set up on your system
+ - in order to deploy Webiny, you must have a valid [AWS account and user credentials](/docs/{version}/infrastructure/aws/configure-aws-credentials) set up on your system
## Project Setup
diff --git a/docs/developer-docs/5.39.x/admin-area/extending/environment-variables.mdx b/docs/developer-docs/5.39.x/admin-area/extending/environment-variables.mdx
index 869e45521..eac5a7fce 100644
--- a/docs/developer-docs/5.39.x/admin-area/extending/environment-variables.mdx
+++ b/docs/developer-docs/5.39.x/admin-area/extending/environment-variables.mdx
@@ -19,7 +19,7 @@ import { WhatYouWillLearn } from "@/components/WhatYouWillLearn";
Admin app relies on several environment variables that get injected into React apps at build time using Pulumi state files. Sometimes, you might want to inject new variables, relevant to your project, and in this article we show you how to do just that.
-Note that the naming convention for environment variables is explained in a dedicated article on [Environment Variables](/docs/core-development-concepts/basics/environment-variables).
+Note that the naming convention for environment variables is explained in a dedicated article on [Environment Variables](/docs/{version}/core-development-concepts/basics/environment-variables).
## Inject Variables from Pulumi State
diff --git a/docs/developer-docs/5.39.x/architecture/api/overview.mdx b/docs/developer-docs/5.39.x/architecture/api/overview.mdx
index 8175024e2..c3953f16a 100644
--- a/docs/developer-docs/5.39.x/architecture/api/overview.mdx
+++ b/docs/developer-docs/5.39.x/architecture/api/overview.mdx
@@ -102,7 +102,7 @@ For background tasks (jobs)-related requirements, Webiny relies on [AWS Step Fun
Note that background tasks are triggered via an Amazon EventBridge event. Amazon EventBridge is deployed as part of the **Core** project application (not shown on the diagram).
-For more information on how to create and execute background tasks, check out the [Background Tasks](/docs/core-development-concepts/background-tasks/about-background-tasks) article.
+For more information on how to create and execute background tasks, check out the [Background Tasks](/docs/{version}/core-development-concepts/background-tasks/about-background-tasks) article.
## FAQ
diff --git a/docs/developer-docs/5.39.x/core-development-concepts/development/local-development.mdx b/docs/developer-docs/5.39.x/core-development-concepts/development/local-development.mdx
index 612ac8fa4..753dc216d 100644
--- a/docs/developer-docs/5.39.x/core-development-concepts/development/local-development.mdx
+++ b/docs/developer-docs/5.39.x/core-development-concepts/development/local-development.mdx
@@ -25,7 +25,7 @@ To do local development in Webiny, the API or any infrastructure changes must be
In summary, changes made to API and infrastructure must be deployed to the cloud during local development. However, for changes made to only UI, deploying to the cloud is not necessary. Once the UI changes are finalised, these changes can be pushed to the cloud.
-If you're wondering how to push changes to the cloud during development, don't worry. As previously mentioned, we have developed various CLI tools, such as the [`watch command`](/docs/core-development-concepts/basics/watch-command) command, to make deploying changes to the cloud during development easy. The command allows you to continuously rebuild and redeploy your code, making the development process seamless.
+If you're wondering how to push changes to the cloud during development, don't worry. As previously mentioned, we have developed various CLI tools, such as the [`watch command`](/docs/{version}/core-development-concepts/basics/watch-command) command, to make deploying changes to the cloud during development easy. The command allows you to continuously rebuild and redeploy your code, making the development process seamless.
Now let's learn more about local development with the frequently asked questions related to Webiny development.
@@ -43,7 +43,7 @@ With that in mind, we don't recommend using tools like [LocalStack](https://www.
## What is the potential cost associated with using an AWS account for development?
-Webiny supports [two database setups](/docs/architecture/introduction#different-database-setups) at the moment:
+Webiny supports [two database setups](/docs/{version}/architecture/introduction#different-database-setups) at the moment:
1. Amazon DynamoDB
2. Amazon DynamoDB + Amazon OpenSearch
@@ -52,7 +52,7 @@ The Amazon DynamoDB database setup fully utilizes serverless services, which mea
On the other hand, with the Amazon DynamoDB + Amazon OpenSearch version, [Amazon OpenSearch Service](https://aws.amazon.com/opensearch-service/) is the only non-serverless service used by Webiny, which is not priced on a pay-per-use basis. This means that you will be charged for the time the service is running, regardless of whether you are using it or not.
-To mitigate costs, you can have one Amazon OpenSearch Service domain that's used by the entire team. This way, you can share the cost of the service among the team members. For more information on how to set this up, please refer to the [Using a Shared Amazon OpenSearch Service Domain](/docs/infrastructure/basics/modify-cloud-infrastructure#using-a-shared-amazon-open-search-service-domain) article.
+To mitigate costs, you can have one Amazon OpenSearch Service domain that's used by the entire team. This way, you can share the cost of the service among the team members. For more information on how to set this up, please refer to the [Using a Shared Amazon OpenSearch Service Domain](/docs/{version}/infrastructure/basics/modify-cloud-infrastructure#using-a-shared-amazon-open-search-service-domain) article.
## Working with team on a Webiny project
diff --git a/docs/developer-docs/5.39.x/enterprise/use-existing-amazon-vpc.mdx b/docs/developer-docs/5.39.x/enterprise/use-existing-amazon-vpc.mdx
index 64f617cca..a8404c82f 100644
--- a/docs/developer-docs/5.39.x/enterprise/use-existing-amazon-vpc.mdx
+++ b/docs/developer-docs/5.39.x/enterprise/use-existing-amazon-vpc.mdx
@@ -91,10 +91,10 @@ Note that, if the Webiny project is being deployed into the production environme
-Production deployment means deploying your Webiny project into `prod` environment, via the [`webiny deploy`](https://www.webiny.com/docs/core-development-concepts/basics/project-deployment) command: `yarn webiny deploy --env prod`.
+Production deployment means deploying your Webiny project into `prod` environment, via the [`webiny deploy`](https://www.webiny.com/docs/{version}/core-development-concepts/basics/project-deployment) command: `yarn webiny deploy --env prod`.
More on the development and production modes can be found here:
-[https://www.webiny.com/docs/architecture/deployment-modes/introduction](https://www.webiny.com/docs/architecture/deployment-modes/introduction)
+[https://www.webiny.com/docs/{version}/architecture/deployment-modes/introduction](https://www.webiny.com/docs/{version}/architecture/deployment-modes/introduction)
@@ -198,7 +198,7 @@ Note that for a Webiny project to work as expected, an Amazon VPC must have an [
1. **Amazon Cognito** - Webiny's application code interacts with Amazon Cognito via AWS SDK. May not be needed if the organization doesn't plan to rely on Amazon Cognito as their identity provider.
2. **Amazon CloudFront** - Webiny's application code interacts with Amazon CloudFront via AWS SDK
-3. **Webiny Control Panel (WCP)** - [Webiny Control Panel (WCP)](/docs/wcp/overview)-linked Webiny projects also frequently interact with app's public HTTP API (`api.webiny.com`)
+3. **Webiny Control Panel (WCP)** - Webiny Control Panel (WCP)-linked Webiny projects also frequently interact with app's public HTTP API (`api.webiny.com`)
4. **Webiny's Prerendering Service** - for website performance reasons, whenever a user publishes a page created with Webiny’s Page Builder application, behind the scenes, an AWS Lambda function is triggered, which issues HTTP requests to published page’s URL (a public CloudFront URL). May not be needed if the organization doesn't plan to use the Page Builder application.
### VPC Endpoints
diff --git a/docs/developer-docs/5.39.x/get-started/install-webiny.mdx b/docs/developer-docs/5.39.x/get-started/install-webiny.mdx
index 0e01de93d..7217b97ac 100644
--- a/docs/developer-docs/5.39.x/get-started/install-webiny.mdx
+++ b/docs/developer-docs/5.39.x/get-started/install-webiny.mdx
@@ -31,7 +31,7 @@ Before proceeding, make sure you have the following:
3. **AWS account and user credentials**
-- in order to deploy Webiny, you must have a valid [AWS account and user credentials](/docs/infrastructure/aws/configure-aws-credentials) set up on your system
+- in order to deploy Webiny, you must have a valid [AWS account and user credentials](/docs/{version}/infrastructure/aws/configure-aws-credentials) set up on your system
## Project Setup
@@ -133,4 +133,4 @@ To install Webiny, you will need a basic understanding of Node, Yarn, JavaScript
### Which AWS regions are supported by Webiny?
-Webiny supports all AWS regions except the China regions (Beijing and Ningxia) because Webiny relies on Amazon CloudFront and Amazon Cognito services, which are not available in [Beijing and Ningxia regions](https://www.amazonaws.cn/en/about-aws/regional-product-services/) respectively.
\ No newline at end of file
+Webiny supports all AWS regions except the China regions (Beijing and Ningxia) because Webiny relies on Amazon CloudFront and Amazon Cognito services, which are not available in [Beijing and Ningxia regions](https://www.amazonaws.cn/en/about-aws/regional-product-services/) respectively.
diff --git a/docs/developer-docs/5.39.x/get-started/welcome.mdx b/docs/developer-docs/5.39.x/get-started/welcome.mdx
index b8e8ad877..e5239d076 100644
--- a/docs/developer-docs/5.39.x/get-started/welcome.mdx
+++ b/docs/developer-docs/5.39.x/get-started/welcome.mdx
@@ -86,7 +86,7 @@ import { ReactComponent as CommunityIcon } from "./assets/resources-icons/commun
categoryTitle="Products"
/>
-
+
Learn how to create plugins and customize the Headless CMS experience to your content needs. From extending the built-in GraphQL capabilities to modifying the editorial experience.
@@ -108,7 +108,7 @@ import { ReactComponent as CommunityIcon } from "./assets/resources-icons/commun
In this section, you'll learn how to customize the layout and visual aspects of your forms.
-
+
The Admin Area is an app inside which all other apps live. You can white-label the UI to match the brand of your customer, introduce new apps into the menu, modify the start page, and more.
@@ -130,7 +130,7 @@ import { ReactComponent as CommunityIcon } from "./assets/resources-icons/commun
For developers just getting started with Webiny, we've prepared a short onboarding video course to help you take your first step in development with Webiny.
-
+
Once you're past the basics of how to develop with Webiny, this category of articles is a good next step.
@@ -138,24 +138,24 @@ import { ReactComponent as CommunityIcon } from "./assets/resources-icons/commun
You'll learn about the core concepts such as the watch command, project organization, the CLI utility and more.
-
+
Learn how to extend the GraphQL API, CLI utility, add custom routes to the Lambda function, intercept requests or customize the built-in Lexical editor.
-
+
If you need to configure and deploy Webiny from a CI/CD environment, follow this guide.
-
+
Webiny has a simple, but powerful security framework that allows you to integrate with different SSO systems as well as customize the authentication and authorization flows.
-
+
Webiny supports long-running tasks that are executed in the background. In this set of articles, you'll learn how to leverage this mechanism inside your own custom plugins and apps built inside Webiny.
@@ -172,7 +172,7 @@ import { ReactComponent as CommunityIcon } from "./assets/resources-icons/commun
categoryTitle="Resources"
/>
-
+
Guides to help non-technical users master Webiny and many of its features.
diff --git a/docs/developer-docs/5.39.x/headless-cms/extending/content-models-via-code.mdx b/docs/developer-docs/5.39.x/headless-cms/extending/content-models-via-code.mdx
index 60cfede45..7046625f5 100644
--- a/docs/developer-docs/5.39.x/headless-cms/extending/content-models-via-code.mdx
+++ b/docs/developer-docs/5.39.x/headless-cms/extending/content-models-via-code.mdx
@@ -42,7 +42,7 @@ In the following sections, we cover a couple of examples that show how to define
Note that we **NEVER** set the `storageId` property value as it is created automatically out of the field `id` and `type` property values.
-To find out more about the `storageId` property, and understand why it exists, please read [this](/docs/headless-cms/extending/content-models-via-code-storage-id) article.
+To find out more about the `storageId` property, and understand why it exists, please read [this](/docs/{version}/headless-cms/extending/content-models-via-code-storage-id) article.
@@ -152,7 +152,7 @@ Once plugins are registered successfully, we should be able to see the following
-With the [`webiny watch`](/docs/core-development-concepts/basics/watch-command) command up and running, the performed application code changes should be automatically rebuilt and redeployed into the cloud.
+With the [`webiny watch`](/docs/{version}/core-development-concepts/basics/watch-command) command up and running, the performed application code changes should be automatically rebuilt and redeployed into the cloud.
@@ -264,7 +264,7 @@ export default [
]
```
-With the [`webiny watch`](/docs/core-development-concepts/basics/watch-command) command up and running,
+With the [`webiny watch`](/docs/{version}/core-development-concepts/basics/watch-command) command up and running,
the performed application code changes should be automatically rebuilt and redeployed into the cloud.
And you should be able to see the following Product model.
@@ -389,7 +389,7 @@ renderer: {
(...)
```
-With the [`webiny watch`](/docs/core-development-concepts/basics/watch-command) command up and running,
+With the [`webiny watch`](/docs/{version}/core-development-concepts/basics/watch-command) command up and running,
the performed application code changes should be automatically rebuilt and redeployed into the cloud.
And you should be able to see the following Product Review model.
@@ -401,7 +401,7 @@ With this [5.39.2 release](/docs/release-notes/5.39.2/changelog#content-models-d
-Additionally, in case the [Folder Level Permissions](/docs/enterprise/aacl/folder-level-permissions) feature is enabled in your Webiny project, the content model entries will not be subject to folder level permissions.
+Additionally, in case the [Folder Level Permissions](/docs/{version}/enterprise/aacl/folder-level-permissions) feature is enabled in your Webiny project, the content model entries will not be subject to folder level permissions.
The following example demonstrates how to disable authorization for a content model and its entries.
@@ -456,7 +456,7 @@ new CmsModelPlugin({
});
```
-With the `authorization` property set to `false`, base authorization checks are disabled for the content model and its entries. Furthermore, in case the [Folder Level Permissions](/docs/enterprise/aacl/folder-level-permissions) feature is enabled in your Webiny project, the content model entries will not be subject to folder level permissions.
+With the `authorization` property set to `false`, base authorization checks are disabled for the content model and its entries. Furthermore, in case the [Folder Level Permissions](/docs/{version}/enterprise/aacl/folder-level-permissions) feature is enabled in your Webiny project, the content model entries will not be subject to folder level permissions.
### Define a Content Model Only for a Specific Locale
diff --git a/docs/developer-docs/5.39.x/headless-cms/extending/lexical-editor.mdx b/docs/developer-docs/5.39.x/headless-cms/extending/lexical-editor.mdx
index c4c108f98..393841872 100644
--- a/docs/developer-docs/5.39.x/headless-cms/extending/lexical-editor.mdx
+++ b/docs/developer-docs/5.39.x/headless-cms/extending/lexical-editor.mdx
@@ -22,7 +22,7 @@ In this article, we'll cover the Lexical Editor configuration for the Headless C
### Toolbar
-Headless CMS uses a static toolbar, which is always visible, unlike the [Page Builder](/docs/page-builder/extending/lexical-editor), which uses a floating toolbar. Webiny ships with a set of default actions, but you can add new actions, replace existing actions, or remove them completely.
+Headless CMS uses a static toolbar, which is always visible. Webiny ships with a set of default actions, but you can add new actions, replace existing actions, or remove them completely.
diff --git a/docs/developer-docs/5.39.x/headless-cms/extending/private-models.mdx b/docs/developer-docs/5.39.x/headless-cms/extending/private-models.mdx
index f5dc87259..f2292c71d 100644
--- a/docs/developer-docs/5.39.x/headless-cms/extending/private-models.mdx
+++ b/docs/developer-docs/5.39.x/headless-cms/extending/private-models.mdx
@@ -32,7 +32,7 @@ Let's delve into the details of both public and private models and explore how y
Public models in Webiny are those content models that are visible within the admin app. These models come with a generated navigation menu, allowing easy access to content entries through the user interface.
Creating public models involves the conventional process of logging into the admin app and using the user interface to create a content model or you can also define public content model via code. The result is the automatic generation of an API, including a GraphQL type and a set of resolvers for seamless data interaction.
-Alternatively, you can also build public models through code using a [plugin](/docs/headless-cms/extending/content-models-via-code-storage-id).
+Alternatively, you can also build public models through code using a [plugin](/docs/{version}/headless-cms/extending/content-models-via-code-storage-id).
## Private Models
Private models, in contrast, remain hidden from the admin app UI. These models are defined programmatically through a plugin. While the schema and resolvers aren't auto-generated, developers have the freedom to design them on the backend or API.
diff --git a/docs/developer-docs/5.39.x/headless-cms/overview.mdx b/docs/developer-docs/5.39.x/headless-cms/overview.mdx
index 5feba1f28..9a09a7c8e 100644
--- a/docs/developer-docs/5.39.x/headless-cms/overview.mdx
+++ b/docs/developer-docs/5.39.x/headless-cms/overview.mdx
@@ -25,17 +25,17 @@ Below you'll find a few core articles that we recommend every engineer to go thr
/>
-
+
Learn what is the Headless CMS GraphQL API, what are its main characteristics, and how to access it.
-
+
Learn how to use the Headless CMS's built-in GraphQL API.
-
+
Learn how to use the Headless CMS's built-in GraphQL API advanced filter.
@@ -52,17 +52,17 @@ Below you'll find a few core articles that we recommend every engineer to go thr
/>
-
+
Learn how to extend the Headless CMS-related GraphQL types and operations.
-
+
Learn how to define content models and content model groups through code.
-
+
Learn how to add, replace, or remove columns in the Entry List Table.
@@ -79,17 +79,17 @@ Below you'll find a few core articles that we recommend every engineer to go thr
/>
-
+
Learn how to build a frontend for Webiny Headless CMS with NextJS
-
+
Learn about Headless CMS lifecycle events, how they work and how to subscribe to a lifecycle event.
-
+
Learn about the date/time and identity-related meta fields that are available for content entries.
diff --git a/docs/developer-docs/5.39.x/headless-cms/references/date-time-and-identity-meta-fields.mdx b/docs/developer-docs/5.39.x/headless-cms/references/date-time-and-identity-meta-fields.mdx
index 30c4a327f..8c062009c 100644
--- a/docs/developer-docs/5.39.x/headless-cms/references/date-time-and-identity-meta-fields.mdx
+++ b/docs/developer-docs/5.39.x/headless-cms/references/date-time-and-identity-meta-fields.mdx
@@ -23,7 +23,7 @@ Apart from the fields that are defined in a content model by the user, all conte
These meta fields are automatically populated by the system, and they can be used to display information about the entry, such as when it was created, modified, or published, and by whom.
-Developers can use these fields when querying entries, for example via the [Headless CMS GraphQL API](/docs/headless-cms/basics/graphql-api):
+Developers can use these fields when querying entries, for example via the [Headless CMS GraphQL API](/docs/{version}/headless-cms/basics/graphql-api):
```graphql
query {
@@ -49,7 +49,7 @@ query {
}
```
-They can also use them in their custom JavaScript (TypeScript) code, for example, when hooking onto [lifecycle events](/docs/headless-cms/references/lifecycle-events):
+They can also use them in their custom JavaScript (TypeScript) code, for example, when hooking onto [lifecycle events](/docs/{version}/headless-cms/references/lifecycle-events):
```typescript
new ContextPlugin(async context => {
diff --git a/docs/developer-docs/5.39.x/infrastructure/basics/modify-cloud-infrastructure.mdx b/docs/developer-docs/5.39.x/infrastructure/basics/modify-cloud-infrastructure.mdx
index d306ac316..f017d86d3 100644
--- a/docs/developer-docs/5.39.x/infrastructure/basics/modify-cloud-infrastructure.mdx
+++ b/docs/developer-docs/5.39.x/infrastructure/basics/modify-cloud-infrastructure.mdx
@@ -197,7 +197,7 @@ export default createCoreApp({
### Defining Multiple Production Environments
-Upon running the [`webiny deploy`](/docs/{version}/core-development-concepts/basics/project-deployment) command, when `prod` is passed as the environment name, a Webiny project is deployed in the so-called [production deployment mode](https://www.webiny.com/docs/architecture/deployment-modes/production).
+Upon running the [`webiny deploy`](/docs/{version}/core-development-concepts/basics/project-deployment) command, when `prod` is passed as the environment name, a Webiny project is deployed in the so-called [production deployment mode](https://www.webiny.com/docs/{version}/architecture/deployment-modes/production).
On order to use the production deployment mode for environments other than `prod`, we can use the `productionEnvironments` parameter. The following example shows how we can use the production mode for the `staging` environment:
diff --git a/docs/developer-docs/5.40.x/admin-area/basics/framework.mdx b/docs/developer-docs/5.40.x/admin-area/basics/framework.mdx
index e739508bc..ded21ccc5 100644
--- a/docs/developer-docs/5.40.x/admin-area/basics/framework.mdx
+++ b/docs/developer-docs/5.40.x/admin-area/basics/framework.mdx
@@ -73,9 +73,9 @@ export const App = () => {
};
```
-The `AddRoute` component is described in the dedicated [Custom Routes](/docs/admin-area/extending/custom-routes) article.
+The `AddRoute` component is described in the dedicated [Custom Routes](/docs/{version}/admin-area/extending/custom-routes) article.
-The `AddMenu` component is described in the dedicated [Customize Navigation](/docs/admin-area/extending/customize-navigation) article.
+The `AddMenu` component is described in the dedicated [Customize Navigation](/docs/{version}/admin-area/extending/customize-navigation) article.
Let's see a more advanced example, and demonstrate a real-life example of menus, routes, and permissions:
@@ -120,7 +120,7 @@ export const App = () => {
- We highly recommend using our [Extensions](/docs/core-development-concepts/basics/extensions) to organize your code in a scalable and portable manner.
+ We highly recommend using our [Extensions](/docs/{version}/core-development-concepts/basics/extensions) to organize your code in a scalable and portable manner.
diff --git a/docs/developer-docs/5.40.x/architecture/api/overview.mdx b/docs/developer-docs/5.40.x/architecture/api/overview.mdx
index 5519d9e5b..7174f7c46 100644
--- a/docs/developer-docs/5.40.x/architecture/api/overview.mdx
+++ b/docs/developer-docs/5.40.x/architecture/api/overview.mdx
@@ -102,7 +102,7 @@ For background tasks (jobs)-related requirements, Webiny relies on [AWS Step Fun
Note that background tasks are triggered via an Amazon EventBridge event. Amazon EventBridge is deployed as part of the **Core** project application (not shown on the diagram).
-For more information on how to create and execute background tasks, check out the [Background Tasks](/docs/core-development-concepts/background-tasks/about-background-tasks) article.
+For more information on how to create and execute background tasks, check out the [Background Tasks](/docs/{version}/core-development-concepts/background-tasks/about-background-tasks) article.
## Additional Information
diff --git a/docs/developer-docs/5.40.x/core-development-concepts/basics/extensions.mdx b/docs/developer-docs/5.40.x/core-development-concepts/basics/extensions.mdx
index 772708731..dd36026b8 100644
--- a/docs/developer-docs/5.40.x/core-development-concepts/basics/extensions.mdx
+++ b/docs/developer-docs/5.40.x/core-development-concepts/basics/extensions.mdx
@@ -23,7 +23,7 @@ There are a couple of types of extensions in Webiny, but the most common ones ar
- **API** - used to extend Webiny's backend functionality (for example its GraphQL API)
- **Cloud Infrastructure** - used to extend the cloud infrastructure Webiny deploys
-For example, via an Admin extension, we can change the [layout of the dashboard](/docs/admin-area/extending/custom-dashboard) or [change the logo](/docs/admin-area/extending/change-logo) that's shown in the header and the main menu. On the other hand, via an API extension, we can introduce new GraphQL queries or mutations, [content models](/docs/headless-cms/extending/content-models-via-code), or [hook into lifecycle events](/docs/headless-cms/references/lifecycle-events).
+For example, via an Admin extension, we can change the [layout of the dashboard](/docs/{version}/admin-area/extending/custom-dashboard) or [change the logo](/docs/{version}/admin-area/extending/change-logo) that's shown in the header and the main menu. On the other hand, via an API extension, we can introduce new GraphQL queries or mutations, [content models](/docs/{version}/headless-cms/extending/content-models-via-code), or [hook into lifecycle events](/docs/{version}/headless-cms/references/lifecycle-events).
## Getting Started
@@ -41,7 +41,7 @@ Ultimately, the scaffold creates the base code for the new extension in the `ext
- There are a couple of cases where the extension code is placed outside of the `extensions` folder. For example, when [modifying cloud infrastructure](/docs/infrastructure/basics/modify-cloud-infrastructure), the code is placed in different `webiny.application.ts` files, located in the `apps` folder.
+ There are a couple of cases where the extension code is placed outside of the `extensions` folder. For example, when [modifying cloud infrastructure](/docs/{version}/infrastructure/basics/modify-cloud-infrastructure), the code is placed in different `webiny.application.ts` files, located in the `apps` folder.
diff --git a/docs/developer-docs/5.40.x/core-development-concepts/extending-and-customizing/extend-graphql-api.mdx b/docs/developer-docs/5.40.x/core-development-concepts/extending-and-customizing/extend-graphql-api.mdx
index e07442382..3e9abbf9c 100644
--- a/docs/developer-docs/5.40.x/core-development-concepts/extending-and-customizing/extend-graphql-api.mdx
+++ b/docs/developer-docs/5.40.x/core-development-concepts/extending-and-customizing/extend-graphql-api.mdx
@@ -91,7 +91,7 @@ With this code in place, we should be able to run the following GraphQL query:
-The easiest way to test it is by using the [API Playground](https://www.webiny.com/docs/admin-area/basics/api-playground) in the Admin app:
+The easiest way to test it is by using the [API Playground](https://www.webiny.com/docs/{version}/admin-area/basics/api-playground) in the Admin app:
Testing the listBooks query in the API Playground>} />
diff --git a/docs/developer-docs/5.40.x/core-development-concepts/security-framework/api-security.mdx b/docs/developer-docs/5.40.x/core-development-concepts/security-framework/api-security.mdx
index 0198f8c66..15559ef84 100644
--- a/docs/developer-docs/5.40.x/core-development-concepts/security-framework/api-security.mdx
+++ b/docs/developer-docs/5.40.x/core-development-concepts/security-framework/api-security.mdx
@@ -17,7 +17,7 @@ In this article, we cover how Webiny Security Framework (_WSF_ for short) works
-This article uses terms like authentication, authorization, identity, and permissions extensively. These terms are described in details in the [Introduction](/docs/core-development-concepts/security-framework/introduction) article. If you're not familiar with these terms, make sure you read that article first.
+This article uses terms like authentication, authorization, identity, and permissions extensively. These terms are described in details in the [Introduction](/docs/{version}/core-development-concepts/security-framework/introduction) article. If you're not familiar with these terms, make sure you read that article first.
diff --git a/docs/developer-docs/5.40.x/core-development-concepts/security-framework/react-security.mdx b/docs/developer-docs/5.40.x/core-development-concepts/security-framework/react-security.mdx
index 1e3131857..f8865afad 100644
--- a/docs/developer-docs/5.40.x/core-development-concepts/security-framework/react-security.mdx
+++ b/docs/developer-docs/5.40.x/core-development-concepts/security-framework/react-security.mdx
@@ -14,7 +14,7 @@ import { Alert } from "@/components/Alert";
-This article is a continuation of the previous two articles about Webiny Security Framework. If you haven't already, please do read the [Introduction](/docs/core-development-concepts/security-framework/introduction) and [API Security](/docs/core-development-concepts/security-framework/api-security) articles before continuing.
+This article is a continuation of the previous two articles about Webiny Security Framework. If you haven't already, please do read the [Introduction](/docs/{version}/core-development-concepts/security-framework/introduction) and [API Security](/docs/{version}/core-development-concepts/security-framework/api-security) articles before continuing.
@@ -28,7 +28,7 @@ Let's use the following diagram to analyze the order of operations that are goin
Once your application has started, it will render a login form (this can be your custom form or the one provided by your IdP's React SDK). A user submits their credentials to the IdP (`1`). If credentials are valid, IdP will return some basic identity information and a JSON Web Token (JWT) (`2`).
-Now that you want to communicate with the Webiny API, you will attach that JWT to every request you make (`3`). The Webiny API will then run the authentication process (`4`) described in the [API Security](/docs/core-development-concepts/security-framework/api-security) article, and verify the JWT (remember, how you implement your authentication plugin is up to you).
+Now that you want to communicate with the Webiny API, you will attach that JWT to every request you make (`3`). The Webiny API will then run the authentication process (`4`) described in the [API Security](/docs/{version}/core-development-concepts/security-framework/api-security) article, and verify the JWT (remember, how you implement your authentication plugin is up to you).
If the identity is valid and is authorized to perform the requested operation, the React application will receive the expected response from the API.
diff --git a/docs/developer-docs/5.40.x/enterprise/advanced-tenant-management.mdx b/docs/developer-docs/5.40.x/enterprise/advanced-tenant-management.mdx
index c13d7dfa1..8c75cdd1f 100644
--- a/docs/developer-docs/5.40.x/enterprise/advanced-tenant-management.mdx
+++ b/docs/developer-docs/5.40.x/enterprise/advanced-tenant-management.mdx
@@ -23,7 +23,7 @@ import customTenantTHeme from "./assets/tenant-management/custom-tenant-theme.pn
## Overview
-Out of the box, Webiny provides a very basic module to manage tenants, called Tenant Manager. We've talked about this module in the article on [Multi-Tenancy](/docs/enterprise/multi-tenancy). This module allows you to create tenants, tag them, and assign custom domains for website routing (assuming you're using our Page Builder to build your website). This works well for managing of a small number of tenants. However, if you need to manage hundreds, or even thousands of tenants, that UI will quickly become unsuitable for the task.
+Out of the box, Webiny provides a very basic module to manage tenants, called Tenant Manager. We've talked about this module in the article on [Multi-Tenancy](/docs/{version}/enterprise/multi-tenancy). This module allows you to create tenants, tag them, and assign custom domains for website routing (assuming you're using our Page Builder to build your website). This works well for managing of a small number of tenants. However, if you need to manage hundreds, or even thousands of tenants, that UI will quickly become unsuitable for the task.
Building a tenant management system to satisfy a wide variety of business use cases is difficult, because every business domain has its own definition of a tenant. In some projects, a tenant would be represented by a "Company", in other projects, tenant would be a "Brand", etc. Webiny allows you to use the tenancy API to closely integrate its tenants (used for data separation), with your business domain, and have a flawless tenant management experience, which follows your business rules.
@@ -62,7 +62,7 @@ in the Webiny Examples repository, and only describing the process and the outco
## Tenant Content Model
-To begin, we need to [create a content model](https://github.com/webiny/webiny-examples/blob/master/cms-tenant-management/5.40.x/extensions/api/src/companyModel.ts) which represents a business tenant in our system, which we'll use to create the low-level tenants within Webiny. We've created a content model plugin via code, as described in the [Define Content Models via Code](/docs/headless-cms/extending/content-models-via-code) article.
+To begin, we need to [create a content model](https://github.com/webiny/webiny-examples/blob/master/cms-tenant-management/5.40.x/extensions/api/src/companyModel.ts) which represents a business tenant in our system, which we'll use to create the low-level tenants within Webiny. We've created a content model plugin via code, as described in the [Define Content Models via Code](/docs/{version}/headless-cms/extending/content-models-via-code) article.
In our example, we named our model _Company_, and created a few basic attributes: `name`, `description`, `theme` (with `primaryColor`, `secondaryColor`, and `logo` attributes), and a hidden boolean attribute called `isInstalled`.
@@ -91,13 +91,13 @@ This is just one way of running a use case; you could achieve the same by implem
-Keep in mind that, if you plan to seed your new tenant with data, depending on the amount of data you're seeding, you will most likely want to move that logic to a [background task](/docs/core-development-concepts/background-tasks/about-background-tasks), since it's not limited by a 30 seconds API Gateway request timeout. Tenant creation and installation could still be executed as described in this example, but to seed a tenant, you would invoke an asynchronous background task.
+Keep in mind that, if you plan to seed your new tenant with data, depending on the amount of data you're seeding, you will most likely want to move that logic to a [background task](/docs/{version}/core-development-concepts/background-tasks/about-background-tasks), since it's not limited by a 30 seconds API Gateway request timeout. Tenant creation and installation could still be executed as described in this example, but to seed a tenant, you would invoke an asynchronous background task.
## Table Column to Install and Access a Tenant
-Now we need to [add a piece of UI](https://github.com/webiny/webiny-examples/blob/master/cms-tenant-management/5.40.x/extensions/admin/src/CompanyEntryList.tsx), in our example it will be a button, to trigger tenant installation. The table customization API is documented in the [Customize Entry List Table Columns](/docs/headless-cms/extending/customize-entry-list-table-columns) article.
+Now we need to [add a piece of UI](https://github.com/webiny/webiny-examples/blob/master/cms-tenant-management/5.40.x/extensions/admin/src/CompanyEntryList.tsx), in our example it will be a button, to trigger tenant installation. The table customization API is documented in the [Customize Entry List Table Columns](/docs/{version}/headless-cms/extending/customize-entry-list-table-columns) article.
diff --git a/docs/developer-docs/5.40.x/get-started/welcome.mdx b/docs/developer-docs/5.40.x/get-started/welcome.mdx
index d8f5f9124..24567ad4f 100644
--- a/docs/developer-docs/5.40.x/get-started/welcome.mdx
+++ b/docs/developer-docs/5.40.x/get-started/welcome.mdx
@@ -86,7 +86,7 @@ import { ReactComponent as CommunityIcon } from "./assets/resources-icons/commun
categoryTitle="Products"
/>
-
+
Learn how to create plugins and customize the Headless CMS experience to your content needs. From extending the built-in GraphQL capabilities to modifying the editorial experience.
@@ -108,7 +108,7 @@ import { ReactComponent as CommunityIcon } from "./assets/resources-icons/commun
In this section, you'll learn how to customize the layout and visual aspects of your forms.
-
+
The Admin Area is an app inside which all other apps live. You can white-label the UI to match the brand of your customer, introduce new apps into the menu, modify the start page, and more.
@@ -130,7 +130,7 @@ import { ReactComponent as CommunityIcon } from "./assets/resources-icons/commun
For developers just getting started with Webiny, we've prepared a short onboarding video course to help you take your first step in development with Webiny.
-
+
Once you're past the basics of how to develop with Webiny, this category of articles is a good next step.
@@ -138,24 +138,24 @@ import { ReactComponent as CommunityIcon } from "./assets/resources-icons/commun
You'll learn about the core concepts such as the watch command, project organization, the CLI utility and more.
-
+
Learn how to extend the GraphQL API, CLI utility, add custom routes to the Lambda function, intercept requests or customize the built-in Lexical editor.
-
+
If you need to configure and deploy Webiny from a CI/CD environment, follow this guide.
-
+
Webiny has a simple, but powerful security framework that allows you to integrate with different SSO systems as well as customize the authentication and authorization flows.
-
+
Webiny supports long-running tasks that are executed in the background. In this set of articles, you'll learn how to leverage this mechanism inside your own custom plugins and apps built inside Webiny.
@@ -172,7 +172,7 @@ import { ReactComponent as CommunityIcon } from "./assets/resources-icons/commun
categoryTitle="Resources"
/>
-
+
Guides to help non-technical users master Webiny and many of its features.
diff --git a/docs/developer-docs/5.40.x/headless-cms/extending/content-entry-live-preview.mdx b/docs/developer-docs/5.40.x/headless-cms/extending/content-entry-live-preview.mdx
index 21ecb2011..4370d1a9f 100644
--- a/docs/developer-docs/5.40.x/headless-cms/extending/content-entry-live-preview.mdx
+++ b/docs/developer-docs/5.40.x/headless-cms/extending/content-entry-live-preview.mdx
@@ -68,7 +68,7 @@ in the Webiny Examples repository, and only describing the process and the outco
## Content Model
-To begin, we need to create an Article content model which represents a website article, which we want to create a Live Preview for. We've provided [an export of the model](https://github.com/webiny/webiny-examples/blob/master/cms-live-preview/5.40.x/article-model.json) which you can simply [import into your own project](/docs/user-guides/headless-cms/advanced/import-export-content-models#importing-content-models).
+To begin, we need to create an Article content model which represents a website article, which we want to create a Live Preview for. We've provided [an export of the model](https://github.com/webiny/webiny-examples/blob/master/cms-live-preview/5.40.x/article-model.json) which you can simply [import into your own project](/docs/{version}/user-guides/headless-cms/advanced/import-export-content-models#importing-content-models).
The `content` field of the Article content model is built using the _Dynamic Zone_ field type, which allows you to define templates that represent your frontend components (blocks of data), which the content creator can then use to write the content within the constraints of the content model.
diff --git a/docs/developer-docs/5.40.x/headless-cms/extending/content-models-via-code.mdx b/docs/developer-docs/5.40.x/headless-cms/extending/content-models-via-code.mdx
index 15edd2fdc..ef2d5b109 100644
--- a/docs/developer-docs/5.40.x/headless-cms/extending/content-models-via-code.mdx
+++ b/docs/developer-docs/5.40.x/headless-cms/extending/content-models-via-code.mdx
@@ -407,7 +407,7 @@ With this [5.39.2 release](/docs/release-notes/5.39.2/changelog#content-models-d
-Additionally, in case the [Folder Level Permissions](/docs/enterprise/aacl/folder-level-permissions) feature is enabled in your Webiny project, the content model entries will not be subject to folder level permissions.
+Additionally, in case the [Folder Level Permissions](/docs/{version}/enterprise/aacl/folder-level-permissions) feature is enabled in your Webiny project, the content model entries will not be subject to folder level permissions.
The following example demonstrates how to disable authorization for a content model and its entries.
@@ -425,7 +425,7 @@ createCmsModelPlugin({
});
```
-With the `authorization` property set to `false`, base authorization checks are disabled for the content model and its entries. Furthermore, in case the [Folder Level Permissions](/docs/enterprise/aacl/folder-level-permissions) feature is enabled in your Webiny project, the content model entries will not be subject to folder level permissions.
+With the `authorization` property set to `false`, base authorization checks are disabled for the content model and its entries. Furthermore, in case the [Folder Level Permissions](/docs/{version}/enterprise/aacl/folder-level-permissions) feature is enabled in your Webiny project, the content model entries will not be subject to folder level permissions.
### Define a Content Model Only for a Specific Locale
@@ -637,7 +637,7 @@ export const createExtension = () => {
### Can I modify the Singular API Name and Plural API Name of a model?
-Modifying the Singular API Name and Plural API Name of a model cannot be done via the UI due to the potential risks involved. However, you can achieve this through the API by using the `updateContentModel` mutation in the [Headless CMS Manage GraphQL API](/docs/headless-cms/basics/graphql-api#manage), accessible in the API Playground.
+Modifying the Singular API Name and Plural API Name of a model cannot be done via the UI due to the potential risks involved. However, you can achieve this through the API by using the `updateContentModel` mutation in the [Headless CMS Manage GraphQL API](/docs/{version}/headless-cms/basics/graphql-api#manage), accessible in the API Playground.
Please be extra caution when using the `updateContentModel` mutation. You must pass the entire content model object, including all fields, during the update. To get all the details about a model, you can use the `getContentModel` API. The reason for passing the complete object is to avoid ambiguity in partial updates, where it is unclear whether you intend to remove a value or keep it unchanged.
diff --git a/docs/developer-docs/5.40.x/headless-cms/extending/private-models.mdx b/docs/developer-docs/5.40.x/headless-cms/extending/private-models.mdx
index 00a11636a..12dc952dc 100644
--- a/docs/developer-docs/5.40.x/headless-cms/extending/private-models.mdx
+++ b/docs/developer-docs/5.40.x/headless-cms/extending/private-models.mdx
@@ -30,7 +30,7 @@ Let's delve into the details of both public and private models and explore how y
Public models in Webiny are those content models that are visible within the admin app. These models come with a generated navigation menu, allowing easy access to content entries through the user interface.
Creating public models involves the conventional process of logging into the admin app and using the user interface to create a content model or you can also define public content model via code. The result is the automatic generation of an API, including a GraphQL type and a set of resolvers for seamless data interaction.
-Alternatively, you can also build public models through code using a [plugin](/docs/headless-cms/extending/content-models-via-code-storage-id).
+Alternatively, you can also build public models through code using a [plugin](/docs/{version}/headless-cms/extending/content-models-via-code-storage-id).
## Private Models
diff --git a/docs/developer-docs/5.40.x/headless-cms/notes-app/react-notes-app.mdx b/docs/developer-docs/5.40.x/headless-cms/notes-app/react-notes-app.mdx
index 1c54a808b..022b9245d 100644
--- a/docs/developer-docs/5.40.x/headless-cms/notes-app/react-notes-app.mdx
+++ b/docs/developer-docs/5.40.x/headless-cms/notes-app/react-notes-app.mdx
@@ -268,7 +268,7 @@ First, create a `graphql` directory in the `src` folder, and then add a `client.
- The `uri` mentioned below is the Manage API URL for the Headless CMS. For more details on how to obtain the Manage API URL, refer to [this guide](/docs/headless-cms/basics/graphql-api#where-to-find-the-url-of-the-graph-ql-api).
+ The `uri` mentioned below is the Manage API URL for the Headless CMS. For more details on how to obtain the Manage API URL, refer to [this guide](/docs/{version}/headless-cms/basics/graphql-api#where-to-find-the-url-of-the-graph-ql-api).
diff --git a/docs/developer-docs/5.40.x/headless-cms/notes-app/webiny-infrastructure-setup.mdx b/docs/developer-docs/5.40.x/headless-cms/notes-app/webiny-infrastructure-setup.mdx
index 7a0aa9af7..a2d73fb78 100644
--- a/docs/developer-docs/5.40.x/headless-cms/notes-app/webiny-infrastructure-setup.mdx
+++ b/docs/developer-docs/5.40.x/headless-cms/notes-app/webiny-infrastructure-setup.mdx
@@ -339,7 +339,7 @@ Additionally, under the Permissions/Content section, select "**All locales**" (a
### Create Note Model to Store User Notes
-As the final step on the Webiny side, we'll create a Note Model to store user notes. If you're new to creating models in Webiny, refer to the [Create Content Model](/docs/user-guides/headless-cms/essentials/create-content-model) user guide.
+As the final step on the Webiny side, we'll create a Note Model to store user notes. If you're new to creating models in Webiny, refer to the [Create Content Model](/docs/{version}/user-guides/headless-cms/essentials/create-content-model) user guide.
We'll set up a Note content model with the following fields:
diff --git a/docs/developer-docs/5.40.x/headless-cms/references/date-time-and-identity-meta-fields.mdx b/docs/developer-docs/5.40.x/headless-cms/references/date-time-and-identity-meta-fields.mdx
index 4f7172798..02c4e0c37 100644
--- a/docs/developer-docs/5.40.x/headless-cms/references/date-time-and-identity-meta-fields.mdx
+++ b/docs/developer-docs/5.40.x/headless-cms/references/date-time-and-identity-meta-fields.mdx
@@ -23,7 +23,7 @@ Apart from the fields that are defined in a content model by the user, all conte
These meta fields are automatically populated by the system, and they can be used to display information about the entry, such as when it was created, modified, or published, and by whom.
-Developers can use these fields when querying entries, for example via the [Headless CMS GraphQL API](/docs/headless-cms/basics/graphql-api):
+Developers can use these fields when querying entries, for example via the [Headless CMS GraphQL API](/docs/{version}/headless-cms/basics/graphql-api):
```graphql
query {
@@ -49,7 +49,7 @@ query {
}
```
-They can also use them in their custom JavaScript (TypeScript) code, for example, when hooking onto [lifecycle events](/docs/headless-cms/references/lifecycle-events):
+They can also use them in their custom JavaScript (TypeScript) code, for example, when hooking onto [lifecycle events](/docs/{version}/headless-cms/references/lifecycle-events):
```typescript
new ContextPlugin(async context => {
diff --git a/docs/developer-docs/5.40.x/infrastructure/basics/modify-cloud-infrastructure.mdx b/docs/developer-docs/5.40.x/infrastructure/basics/modify-cloud-infrastructure.mdx
index a0fad6380..5d1b62584 100644
--- a/docs/developer-docs/5.40.x/infrastructure/basics/modify-cloud-infrastructure.mdx
+++ b/docs/developer-docs/5.40.x/infrastructure/basics/modify-cloud-infrastructure.mdx
@@ -195,7 +195,7 @@ export default createCoreApp({
### Defining Multiple Production Environments
-Upon running the [`webiny deploy`](/docs/{version}/core-development-concepts/basics/project-deployment) command, when `prod` is passed as the environment name, a Webiny project is deployed in the so-called [production deployment mode](https://www.webiny.com/docs/architecture/deployment-modes/production).
+Upon running the [`webiny deploy`](/docs/{version}/core-development-concepts/basics/project-deployment) command, when `prod` is passed as the environment name, a Webiny project is deployed in the so-called [production deployment mode](https://www.webiny.com/docs/{version}/architecture/deployment-modes/production).
On order to use the production deployment mode for environments other than `prod`, we can use the `productionEnvironments` parameter. The following example shows how we can use the production mode for the `staging` environment:
diff --git a/docs/developer-docs/5.40.x/infrastructure/pulumi-iac/iac-with-pulumi.mdx b/docs/developer-docs/5.40.x/infrastructure/pulumi-iac/iac-with-pulumi.mdx
index ccb266477..ab100367c 100644
--- a/docs/developer-docs/5.40.x/infrastructure/pulumi-iac/iac-with-pulumi.mdx
+++ b/docs/developer-docs/5.40.x/infrastructure/pulumi-iac/iac-with-pulumi.mdx
@@ -39,7 +39,7 @@ In the background, all of these applications are standalone [Pulumi projects](ht
1. every project application contains its own infrastructure-related code ([Pulumi program](https://www.pulumi.com/docs/intro/concepts/programming-model/#programs)), configuration, meta, and [state files](/docs/{version}/infrastructure/pulumi-iac/iac-with-pulumi#state-files)
-2. upon fully deploying a Webiny project via the [`webiny deploy`](/docs/core-development-concepts/basics/project-deployment) command, applications are deployed separately, one by one, in the same order as listed above
+2. upon fully deploying a Webiny project via the [`webiny deploy`](/docs/{version}/core-development-concepts/basics/project-deployment) command, applications are deployed separately, one by one, in the same order as listed above
@@ -62,7 +62,7 @@ Still, in some cases, users may need to modify the cloud infrastructure code. Fo
To learn more about how to modify the cloud infrastructure code, please refer to the [Modify Cloud
- Infrastructure](/docs/infrastructure/basics/modify-cloud-infrastructure) article.
+ Infrastructure](/docs/{version}/infrastructure/basics/modify-cloud-infrastructure) article.
diff --git a/docs/developer-docs/5.41.x/core-development-concepts/basics/extensions.mdx b/docs/developer-docs/5.41.x/core-development-concepts/basics/extensions.mdx
index 39894b15d..d2291c5ca 100644
--- a/docs/developer-docs/5.41.x/core-development-concepts/basics/extensions.mdx
+++ b/docs/developer-docs/5.41.x/core-development-concepts/basics/extensions.mdx
@@ -23,7 +23,7 @@ There are a couple of types of extensions in Webiny, but the most common ones ar
- **API** - used to extend Webiny's backend functionality (for example its GraphQL API)
- **Cloud Infrastructure** - used to extend the cloud infrastructure Webiny deploys
-For example, via an Admin extension, we can change the [layout of the dashboard](/docs/admin-area/extending/custom-dashboard) or [change the logo](/docs/admin-area/extending/change-logo) that's shown in the header and the main menu. On the other hand, via an API extension, we can introduce new GraphQL queries or mutations, [content models](/docs/headless-cms/extending/content-models-via-code), or [hook into lifecycle events](/docs/headless-cms/references/lifecycle-events).
+For example, via an Admin extension, we can change the [layout of the dashboard](/docs/{version}/admin-area/extending/custom-dashboard) or [change the logo](/docs/{version}/admin-area/extending/change-logo) that's shown in the header and the main menu. On the other hand, via an API extension, we can introduce new GraphQL queries or mutations, [content models](/docs/{version}/headless-cms/extending/content-models-via-code), or [hook into lifecycle events](/docs/{version}/headless-cms/references/lifecycle-events).
## Getting Started
@@ -41,7 +41,7 @@ Once all the questions are answered, the command creates the base code for the n
- There are a couple of cases where the extension code is placed outside of the `extensions` folder. For example, when [modifying cloud infrastructure](/docs/infrastructure/basics/modify-cloud-infrastructure), the code is placed in different `webiny.application.ts` files, located in the `apps` folder.
+ There are a couple of cases where the extension code is placed outside of the `extensions` folder. For example, when [modifying cloud infrastructure](/docs/{version}/infrastructure/basics/modify-cloud-infrastructure), the code is placed in different `webiny.application.ts` files, located in the `apps` folder.
diff --git a/docs/developer-docs/5.41.x/core-development-concepts/basics/watch-command.mdx b/docs/developer-docs/5.41.x/core-development-concepts/basics/watch-command.mdx
index a91c5e6ac..ee888a969 100644
--- a/docs/developer-docs/5.41.x/core-development-concepts/basics/watch-command.mdx
+++ b/docs/developer-docs/5.41.x/core-development-concepts/basics/watch-command.mdx
@@ -45,7 +45,7 @@ yarn webiny watch website --env dev
- Extensions are the primary way to develop on top Webiny and extend it. To learn more, check out the [Extensions](/docs/core-development-concepts/basics/extensions) article.
+ Extensions are the primary way to develop on top Webiny and extend it. To learn more, check out the [Extensions](/docs/{version}/core-development-concepts/basics/extensions) article.
diff --git a/docs/developer-docs/5.41.x/enterprise/aacl/teams.mdx b/docs/developer-docs/5.41.x/enterprise/aacl/teams.mdx
index 5f7e8e646..63af86cc9 100644
--- a/docs/developer-docs/5.41.x/enterprise/aacl/teams.mdx
+++ b/docs/developer-docs/5.41.x/enterprise/aacl/teams.mdx
@@ -33,11 +33,11 @@ And although this approach might work for some users, it can quickly become cumb
This feature is especially useful for larger organizations, where it's common to have multiple teams working on different projects. Also, it's a great way to simplify the process of managing permissions for multiple users, as you can simply assign a role to a team, instead of assigning it to each individual user.
-Additionally, the Teams feature can be used in conjunction with [Folder Level Permissions (FLP)](/docs/enterprise/aacl/folder-level-permissions) to further enhance the security of your Webiny project. Instead of just being able to define folder level permissions for individual users, you can now define them for teams as well. Make sure to check out the FLP documentation to learn more about this feature.
+Additionally, the Teams feature can be used in conjunction with [Folder Level Permissions (FLP)](/docs/{version}/enterprise/aacl/folder-level-permissions) to further enhance the security of your Webiny project. Instead of just being able to define folder level permissions for individual users, you can now define them for teams as well. Make sure to check out the FLP documentation to learn more about this feature.
## Enabling Teams and Feature Overview
-For Webiny Enterprise users, apart from [linking their Webiny project](/docs/wcp/link-a-project) with Webiny Control Panel (WCP), there are no additional steps required to enable Teams.
+For Webiny Enterprise users, apart from [linking their Webiny project](/docs/{version}/wcp/link-a-project) with Webiny Control Panel (WCP), there are no additional steps required to enable Teams.
Once linked, Teams will be automatically enabled and the module can be accessed from the main menu:
diff --git a/docs/developer-docs/5.41.x/enterprise/auth0-integration.mdx b/docs/developer-docs/5.41.x/enterprise/auth0-integration.mdx
index b9dc6c467..154ab43eb 100644
--- a/docs/developer-docs/5.41.x/enterprise/auth0-integration.mdx
+++ b/docs/developer-docs/5.41.x/enterprise/auth0-integration.mdx
@@ -136,7 +136,7 @@ export default ({ documentClient }: { documentClient: DocumentClient }) => [
+ groups: [token["webiny_group"]]
+
+ // With the Teams feature enabled, you can also assign teams to the user.
-+ // Learn more: https://www.webiny.com/docs/enterprise/aacl/teams
++ // Learn more: https://www.webiny.com/docs/{version}/enterprise/aacl/teams
+ // teams: [token["webiny_team"]]
+
+ // Assign any custom values you might need.
diff --git a/docs/developer-docs/5.41.x/enterprise/okta-integration.mdx b/docs/developer-docs/5.41.x/enterprise/okta-integration.mdx
index bd18cbebc..16b178576 100644
--- a/docs/developer-docs/5.41.x/enterprise/okta-integration.mdx
+++ b/docs/developer-docs/5.41.x/enterprise/okta-integration.mdx
@@ -134,7 +134,7 @@ export default ({ documentClient }: { documentClient: DocumentClient }) => [
+ groups: [token["webiny_group"]]
+
+ // With the Teams feature enabled, you can also assign teams to the user.
-+ // Learn more: https://www.webiny.com/docs/enterprise/aacl/teams
++ // Learn more: https://www.webiny.com/docs/{version}/enterprise/aacl/teams
+ // teams: [token["webiny_team"]]
+
+ // Assign any custom values you might need.
diff --git a/docs/developer-docs/5.41.x/headless-cms/ai/smart-seo-open-ai.mdx b/docs/developer-docs/5.41.x/headless-cms/ai/smart-seo-open-ai.mdx
index 93f117266..df18044b9 100644
--- a/docs/developer-docs/5.41.x/headless-cms/ai/smart-seo-open-ai.mdx
+++ b/docs/developer-docs/5.41.x/headless-cms/ai/smart-seo-open-ai.mdx
@@ -61,11 +61,11 @@ Details on this are covered in the sections below. For now, let’s deploy the A
yarn webiny deploy api --env ENVIRONMENT_NAME
```
-Alternatively, you can use the watch command, which continuously rebuild and redeploy your code. Learn more about it [here](/docs/core-development-concepts/basics/watch-command).
+Alternatively, you can use the watch command, which continuously rebuild and redeploy your code. Learn more about it [here](/docs/{version}/core-development-concepts/basics/watch-command).
## Run the Project
-After downloading the extension to your project, run the [webiny watch](/docs/core-development-concepts/basics/watch-command) command to see the Smart SEO functionality in action.
+After downloading the extension to your project, run the [webiny watch](/docs/{version}/core-development-concepts/basics/watch-command) command to see the Smart SEO functionality in action.
```bash
yarn webiny watch admin --env ENVIRONMENT_NAME
@@ -78,7 +78,7 @@ You’re now ready to generate SEO titles and tags for your articles using OpenA
## Code Walkthrough
-Let’s walk through the code to understand how the Smart SEO extension operates. We’ve created a new [extension](/docs/core-development-concepts/basics/extensions) called [`smart-seo-open-ai`](https://github.com/webiny/webiny-examples/tree/master/headless-cms/smart-seo-open-ai/5.41.x/extensions/smartSeoOpenAi), and we’ll review each plugin used in this extension one by one.
+Let’s walk through the code to understand how the Smart SEO extension operates. We’ve created a new [extension](/docs/{version}/core-development-concepts/basics/extensions) called [`smart-seo-open-ai`](https://github.com/webiny/webiny-examples/tree/master/headless-cms/smart-seo-open-ai/5.41.x/extensions/smartSeoOpenAi), and we’ll review each plugin used in this extension one by one.
### Field Tracker, ContentEntry Form Decorator
In this example, we have an **Article - Smart SEO** Model with four fields: **Content**, **SEO - Title**, **SEO - Description**, and **SEO - Meta Tags**. We will track these fields. Once the Content field is populated, we will send it to OpenAI, which will generate SEO-friendly titles and tags for the article. The generated title and tags will then be set in the respective **Title**, **Description** and **Tags** fields of the model.
@@ -102,7 +102,7 @@ Webiny leverages the [Lexical text editor](https://lexical.dev/) for Rich Text F
### Extend Headless CMS GraphQL API
-In this example, we [extended the Headless CMS GraphQL API](/docs/headless-cms/extending/extend-graphql-api) to generate SEO data using the OpenAI API. The [`generateSeo` plugin](https://github.com/webiny/webiny-examples/blob/master/headless-cms/smart-seo-open-ai/5.41.x/extensions/smartSeoOpenAi/api/src/generateSeo.ts) integrates Webiny with OpenAI. We created a `generateSeo` query for the same.
+In this example, we [extended the Headless CMS GraphQL API](/docs/{version}/headless-cms/extending/extend-graphql-api) to generate SEO data using the OpenAI API. The [`generateSeo` plugin](https://github.com/webiny/webiny-examples/blob/master/headless-cms/smart-seo-open-ai/5.41.x/extensions/smartSeoOpenAi/api/src/generateSeo.ts) integrates Webiny with OpenAI. We created a `generateSeo` query for the same.
To prevent exposing our OpenAI API key to the public, we avoid calling the OpenAI API from the client side. Instead, we handle it server-side by creating this `generateSeo` plugin that extends the Headless CMS GraphQL API for secure SEO data generation. This plugin sends content to OpenAI and retrieves SEO-related information.
diff --git a/docs/developer-docs/5.41.x/headless-cms/extending/customize-entry-list-bulk-actions.mdx b/docs/developer-docs/5.41.x/headless-cms/extending/customize-entry-list-bulk-actions.mdx
index 3f4530867..19e5ee0a7 100644
--- a/docs/developer-docs/5.41.x/headless-cms/extending/customize-entry-list-bulk-actions.mdx
+++ b/docs/developer-docs/5.41.x/headless-cms/extending/customize-entry-list-bulk-actions.mdx
@@ -250,7 +250,7 @@ By declaring the `modelIds` prop, you can define in which Content Model Entry Li
### Bulk Action via Background Task
-When working with large datasets, performing bulk actions in the background is essential for maintaining a smooth user experience. Webiny allows editors to perform bulk actions asynchronously in the background, eliminating the need for sequential processing on the client side. This functionality is powered by the [Webiny background task feature](/docs/core-development-concepts/background-tasks/about-background-tasks), which simplifies large-scale operations.
+When working with large datasets, performing bulk actions in the background is essential for maintaining a smooth user experience. Webiny allows editors to perform bulk actions asynchronously in the background, eliminating the need for sequential processing on the client side. This functionality is powered by the [Webiny background task feature](/docs/{version}/core-development-concepts/background-tasks/about-background-tasks), which simplifies large-scale operations.
In this tutorial, we'll walk you through creating a plugin to enable bulk actions in the background. You don't need to be familiar with the background task infrastructure, as Webiny provides simplified APIs that allow you to focus on your business logic.
diff --git a/docs/developer-docs/5.41.x/page-builder/extending/create-a-page-element.mdx b/docs/developer-docs/5.41.x/page-builder/extending/create-a-page-element.mdx
index bcfcdda47..5bc6d31df 100644
--- a/docs/developer-docs/5.41.x/page-builder/extending/create-a-page-element.mdx
+++ b/docs/developer-docs/5.41.x/page-builder/extending/create-a-page-element.mdx
@@ -181,7 +181,7 @@ export const SpaceX = createRenderer(() => {
```
-As we can see in the code, in order to be able to issue remote GraphQL queries, we're using the [`graphql-request`](https://www.npmjs.com/package/graphql-request) library, which we've specified as our extension's dependency upon running the [`webiny extension`](/docs/core-development-concepts/basics/webiny-cli#yarn-webiny-extension) command in the [Getting Started](#getting-started) section.
+As we can see in the code, in order to be able to issue remote GraphQL queries, we're using the [`graphql-request`](https://www.npmjs.com/package/graphql-request) library, which we've specified as our extension's dependency upon running the [`webiny extension`](/docs/{version}/core-development-concepts/basics/webiny-cli#yarn-webiny-extension) command in the [Getting Started](#getting-started) section.
Note that our GraphQL query is called within the `useLoader` React hook. This is important because, essentially, this enables proper data caching when the page is published. This way, the page element is rendered efficiently, without the need to re-fetch the data each time the page is loaded.
diff --git a/docs/developer-docs/5.41.x/page-builder/extending/loading-data-in-page-elements.mdx b/docs/developer-docs/5.41.x/page-builder/extending/loading-data-in-page-elements.mdx
index 0f117877d..3a2f01ce9 100644
--- a/docs/developer-docs/5.41.x/page-builder/extending/loading-data-in-page-elements.mdx
+++ b/docs/developer-docs/5.41.x/page-builder/extending/loading-data-in-page-elements.mdx
@@ -21,7 +21,7 @@ import dataLoadedWithoutLoader from "./assets/loading-data-in-page-elements/load
It's not uncommon to have a custom page element that loads data from an external remote HTTP API and displays it on the page.
-For example, you might want to display a list of products or a list of blog posts that are loaded from [Webiny's Headless CMS GraphQL API](/docs/headless-cms/basics/graphql-api). Another examples is listing rocket and dragon spacecrafts from an external SpaceX API, which is covered in the [Create a Custom Page Element](/docs/page-builder/extending/create-a-page-element) guide.
+For example, you might want to display a list of products or a list of blog posts that are loaded from [Webiny's Headless CMS GraphQL API](/docs/{version}/headless-cms/basics/graphql-api). Another examples is listing rocket and dragon spacecrafts from an external SpaceX API, which is covered in the [Create a Custom Page Element](/docs/{version}/page-builder/extending/create-a-page-element) guide.
In this guide, we show how to efficiently load data in Page Builder elements using the `useLoader` React hook.
@@ -54,7 +54,7 @@ Let's analyze the code that was used to create the page element we saw in the vi
- If you're not familiar with creating custom page elements, you can learn more about it in the [Create a Custom Page Element](/docs/page-builder/extending/create-a-page-element) guide.
+ If you're not familiar with creating custom page elements, you can learn more about it in the [Create a Custom Page Element](/docs/{version}/page-builder/extending/create-a-page-element) guide.
diff --git a/docs/developer-docs/5.41.x/security/extensions/programmatically-create-roles-and-teams.mdx b/docs/developer-docs/5.41.x/security/extensions/programmatically-create-roles-and-teams.mdx
index 4db204da5..97ac720d9 100644
--- a/docs/developer-docs/5.41.x/security/extensions/programmatically-create-roles-and-teams.mdx
+++ b/docs/developer-docs/5.41.x/security/extensions/programmatically-create-roles-and-teams.mdx
@@ -33,7 +33,7 @@ The most straightforward way to define roles and teams would be via the Admin Ar
- Note that the Teams feature is part of our enterprise offering. To learn more, please check out the [Teams](/docs/enterprise/aacl/teams) article.
+ Note that the Teams feature is part of our enterprise offering. To learn more, please check out the [Teams](/docs/{version}/enterprise/aacl/teams) article.
@@ -103,7 +103,7 @@ The easiest way to find out which permissions are available and to build roles w
- More info on security permissions can also be found in the [Security Framework - Introduction](/docs/security/security-framework/introduction#permission) article.
+ More info on security permissions can also be found in the [Security Framework - Introduction](/docs/{version}/security/security-framework/introduction#permission) article.
@@ -149,7 +149,7 @@ With this code in place, we should be able to see the following team in the Team
- Note that the Teams feature is part of our enterprise offering. To learn more, please check out the [Teams](/docs/enterprise/aacl/teams) article.
+ Note that the Teams feature is part of our enterprise offering. To learn more, please check out the [Teams](/docs/{version}/enterprise/aacl/teams) article.
diff --git a/docs/developer-docs/5.42.x/headless-cms/extending/content-models-via-code.mdx b/docs/developer-docs/5.42.x/headless-cms/extending/content-models-via-code.mdx
index 9a3367010..c97c4a887 100644
--- a/docs/developer-docs/5.42.x/headless-cms/extending/content-models-via-code.mdx
+++ b/docs/developer-docs/5.42.x/headless-cms/extending/content-models-via-code.mdx
@@ -420,7 +420,7 @@ With this [5.39.2 release](/docs/release-notes/5.39.2/changelog#content-models-d
-Additionally, in case the [Folder Level Permissions](/docs/enterprise/aacl/folder-level-permissions) feature is enabled in your Webiny project, the content model entries will not be subject to folder level permissions.
+Additionally, in case the [Folder Level Permissions](/docs/{version}/enterprise/aacl/folder-level-permissions) feature is enabled in your Webiny project, the content model entries will not be subject to folder level permissions.
The following example demonstrates how to disable authorization for a content model and its entries.
@@ -438,7 +438,7 @@ createModelPlugin({
});
```
-With the `authorization` property set to `false`, base authorization checks are disabled for the content model and its entries. Furthermore, in case the [Folder Level Permissions](/docs/enterprise/aacl/folder-level-permissions) feature is enabled in your Webiny project, the content model entries will not be subject to folder level permissions.
+With the `authorization` property set to `false`, base authorization checks are disabled for the content model and its entries. Furthermore, in case the [Folder Level Permissions](/docs/{version}/enterprise/aacl/folder-level-permissions) feature is enabled in your Webiny project, the content model entries will not be subject to folder level permissions.
### Define a Content Model Only for a Specific Locale
@@ -660,7 +660,7 @@ export const createExtension = () => {
### Can I modify the Singular API Name and Plural API Name of a model?
-Modifying the Singular API Name and Plural API Name of a model cannot be done via the UI due to the potential risks involved. However, you can achieve this through the API by using the `updateContentModel` mutation in the [Headless CMS Manage GraphQL API](/docs/headless-cms/basics/graphql-api#manage), accessible in the API Playground.
+Modifying the Singular API Name and Plural API Name of a model cannot be done via the UI due to the potential risks involved. However, you can achieve this through the API by using the `updateContentModel` mutation in the [Headless CMS Manage GraphQL API](/docs/{version}/headless-cms/basics/graphql-api#manage), accessible in the API Playground.
Please be extra caution when using the `updateContentModel` mutation. You must pass the entire content model object, including all fields, during the update. To get all the details about a model, you can use the `getContentModel` API. The reason for passing the complete object is to avoid ambiguity in partial updates, where it is unclear whether you intend to remove a value or keep it unchanged.
diff --git a/docs/developer-docs/5.43.x/core-development-concepts/background-tasks/built-in-background-tasks.mdx b/docs/developer-docs/5.43.x/core-development-concepts/background-tasks/built-in-background-tasks.mdx
index 97ba447dd..9d26d9d6f 100644
--- a/docs/developer-docs/5.43.x/core-development-concepts/background-tasks/built-in-background-tasks.mdx
+++ b/docs/developer-docs/5.43.x/core-development-concepts/background-tasks/built-in-background-tasks.mdx
@@ -25,7 +25,7 @@ The following is a list of background tasks that are included in Webiny by defau
- This task can be used with the Amazon DynamoDB + Amazon OpenSearch [database setup](/docs/architecture/introduction#different-database-setups). It can be also used with the legacy Amazon DynamoDB + Amazon Elasticsearch setup.
+ This task can be used with the Amazon DynamoDB + Amazon OpenSearch [database setup](/docs/{version}/architecture/introduction#different-database-setups). It can be also used with the legacy Amazon DynamoDB + Amazon Elasticsearch setup.
@@ -82,7 +82,7 @@ This is done to reduce the strain on the Elasticsearch/OpenSearch cluster as the
- This task can be used with the Amazon DynamoDB + Amazon OpenSearch [database setup](/docs/architecture/introduction#different-database-setups). It can be also used with the legacy Amazon DynamoDB + Amazon Elasticsearch setup.
+ This task can be used with the Amazon DynamoDB + Amazon OpenSearch [database setup](/docs/{version}/architecture/introduction#different-database-setups). It can be also used with the legacy Amazon DynamoDB + Amazon Elasticsearch setup.
diff --git a/docs/developer-docs/6.0.x/basic/di.ai.txt b/docs/developer-docs/6.0.x/basic/di.ai.txt
new file mode 100644
index 000000000..77920587f
--- /dev/null
+++ b/docs/developer-docs/6.0.x/basic/di.ai.txt
@@ -0,0 +1,118 @@
+AI Context: Dependency Injection (di.mdx)
+
+Source of Information:
+1. Read the @webiny/di package README from the linked repository (https://github.com/webiny/di)
+2. Analyzed the di-readme.md file that was provided in the 6.0.x folder
+3. Examined existing examples in 6.0.x files to understand how abstractions and implementations are used in practice
+4. Reviewed the CreateEntryUseCase abstraction example, which showed:
+ - How to use createAbstraction
+ - Interface definition patterns
+ - Namespace exports pattern
+ - Error type definitions
+ - Proper TypeScript typing
+
+Understanding Dependency Injection (DI):
+DI is a pattern where you don't create dependencies directly in your code. Instead, you define what you need (interface/abstraction) and something else provides it (implementation). This makes code:
+- Testable: Easy to swap real services with test doubles
+- Flexible: Can change implementations without changing code
+- Maintainable: Clear separation of "what" vs "how"
+
+Simple Analogy:
+Think of ordering food at a restaurant. You say "I want a burger" (interface/abstraction). The kitchen decides how to make it (implementation). You don't care if they use oven A or oven B, you just want a burger.
+
+In the DI System:
+1. Abstraction = The "what" (interface) - "I need something that can save users"
+2. Implementation = The "how" (concrete code) - "Here's code that saves users to database"
+3. Container = The system that connects requests to services
+
+External Package Used:
+This system uses @webiny/di - a type-safe dependency injection library designed for TypeScript.
+
+Key Documentation Decisions:
+- Focus on createAbstraction and createImplementation API
+- Keep examples simple and generic (Book/Author/Category domain)
+- Show the namespace pattern used throughout codebase
+- Export everything users need from the namespace (types, interfaces, errors)
+- Demonstrate the Result pattern integration
+- Use the prefix pattern for abstraction names (e.g., "Library/CreateBook")
+- Did not include automatic discovery or advanced topics
+- Removed comments from example code except for pedagogical correct/wrong comparisons
+
+Example Pattern Used:
+- Interface definition
+- Error types definition
+- createAbstraction call
+- Namespace export with all necessary types
+- const export of the abstraction
+- createImplementation usage from the namespace
+
+The 5-Step Pattern:
+
+Step 1: Define the Interface (What you need)
+```typescript
+export interface ISaveBookUseCase {
+ execute(book: Book): Promise>;
+}
+```
+
+Step 2: Define Error Types
+```typescript
+export interface ISaveBookUseCaseErrors {
+ validation: ValidationError;
+ database: DatabaseError;
+}
+type UseCaseError = ISaveBookUseCaseErrors[keyof ISaveBookUseCaseErrors];
+```
+
+Step 3: Create the Abstraction (Register it)
+```typescript
+export const SaveBookUseCase = createAbstraction("Library/SaveBook");
+```
+The string "Library/SaveBook" is a unique name (like an ID) for this abstraction.
+
+Step 4: Export Everything in a Namespace
+```typescript
+export namespace SaveBookUseCase {
+ export type Interface = ISaveBookUseCase;
+ export type Error = UseCaseError;
+ // Export all types someone needs to use or implement this
+}
+```
+Why? So users have everything in one place: SaveBookUseCase.Interface, SaveBookUseCase.Error
+
+Step 5: Create Implementation (The actual code)
+```typescript
+export const saveBookUseCase = SaveBookUseCase.createImplementation({
+ database: DatabaseService // Dependencies it needs
+}, async ({ database }, book) => {
+ // Your actual logic here
+ await database.save(book);
+ return Result.ok(book);
+});
+```
+
+Related Documents:
+- See headless-cms/use-case/*.mdx for real-world abstraction examples
+- See headless-cms/event-handler/*.mdx for implementation examples
+- See basic/result.mdx for the Result pattern (used with DI)
+
+Key Code Locations:
+- @webiny/di package: https://github.com/webiny/di
+- Example abstractions: Look in extensions/[module]/[feature]/abstraction/
+- Example implementations: Look in extensions/[module]/[feature]/useCase/
+
+To examine source code implementations in detail, access to the Webiny project repository is needed.
+
+Common Patterns to Follow:
+1. Always export both namespace and const
+2. Use Result pattern for error handling
+3. Prefix abstraction names (e.g., "Cms/CreateEntry")
+4. Export all types users need from namespace
+5. Keep examples generic (avoid CMS-specific examples in this doc)
+
+Tone Guidelines:
+- Be concise and technical
+- Focus on what's unique to this DI implementation
+- Show complete patterns with all 5 steps
+- Mention @webiny/di as the external package being used
+
diff --git a/docs/developer-docs/6.0.x/basic/di.mdx b/docs/developer-docs/6.0.x/basic/di.mdx
new file mode 100644
index 000000000..2955c1637
--- /dev/null
+++ b/docs/developer-docs/6.0.x/basic/di.mdx
@@ -0,0 +1,267 @@
+---
+id: kp9m2xnf
+title: Dependency Injection
+description: Creating abstractions and implementations in Webiny
+---
+
+import {Alert} from "@/components/Alert";
+
+
+
+- How to create an abstraction?
+- How to create an implementation of an abstraction?
+- How to declare dependencies?
+- How to use the decorator pattern?
+
+
+
+## Overview
+
+Webiny uses `@webiny/di`, a type-safe dependency injection container built for SOLID principles. The core concept is `Abstraction`, which unifies tokens and types for compile-time safety. As a developer, you create implementations using `createImplementation()` and export them.
+
+## Creating an Abstraction
+
+An abstraction is a type-safe token that represents an interface. Use `createAbstraction()` to create one:
+
+```typescript
+import { createAbstraction, Result } from "webiny/api";
+import type { IBook } from "~/types/index.js";
+
+interface IBookRepository {
+ getById(id: string): Promise>;
+ save(book: IBook): Promise>;
+}
+
+const BookRepository = createAbstraction("Library/BookRepository");
+
+namespace BookRepository {
+ export type Interface = IBookRepository;
+ export type Book = IBook;
+}
+
+export { BookRepository };
+```
+
+**Naming Convention:**
+- The abstraction name typically matches the interface name without the `I` prefix
+- Use a prefix to organize abstractions by domain (e.g., `Library/BookRepository`, `Store/CreateOrder`)
+
+**Namespace Pattern:** Use a namespace with the same name as the abstraction to export related types. Export everything implementers will need - the interface, domain types, input/output types, etc. This allows consumers to use `BookRepository.Interface` and `BookRepository.Book` without additional imports.
+
+### Advanced Namespace Pattern
+
+For more complex abstractions like use cases, you can organize additional types in the namespace:
+
+```typescript
+import { createAbstraction, Result } from "webiny/api";
+import type { IBook, IAuthor, ICategory } from "~/types/index.js";
+
+interface ICreateBookUseCase {
+ execute(input: CreateBookInput): Promise>;
+}
+
+interface CreateBookInput {
+ title: string;
+ authorId: string;
+ categoryId: string;
+}
+
+type CreateBookError = ValidationError | AuthorizationError;
+
+const CreateBookUseCase = createAbstraction("Library/CreateBook");
+
+namespace CreateBookUseCase {
+ export type Interface = ICreateBookUseCase;
+ export type Input = CreateBookInput;
+ export type Error = CreateBookError;
+ export type Return = Promise>;
+ export type Book = IBook;
+ export type Author = IAuthor;
+ export type Category = ICategory;
+}
+
+export { CreateBookUseCase };
+```
+
+This pattern allows consumers to reference all related types through the abstraction:
+- `CreateBookUseCase.Interface` - for implementing the use case
+- `CreateBookUseCase.Input` - for the input parameters
+- `CreateBookUseCase.Error` - for error types
+- `CreateBookUseCase.Return` - for the return type
+- `CreateBookUseCase.Book`, `CreateBookUseCase.Author`, `CreateBookUseCase.Category` - domain types needed by implementers
+
+**Key Principle:** Export everything an implementer needs. This creates a complete, self-contained abstraction where consumers only need to import the abstraction itself.
+
+## Creating an Implementation
+
+Use `createImplementation()` from the abstraction to bind your class to it. This method is available on every abstraction and requires three properties:
+
+```typescript
+import { BookRepository } from "./abstractions/BookRepository.js";
+import { Result } from "webiny/api";
+
+class InMemoryBookRepository implements BookRepository.Interface {
+ private books = new Map();
+
+ public async getById(id: string): Promise> {
+ const book = this.books.get(id);
+ if (!book) {
+ return Result.fail(new NotFoundError("Book not found"));
+ }
+ return Result.ok(book);
+ }
+
+ public async save(book: BookRepository.Book): Promise> {
+ this.books.set(book.id, book);
+ return Result.ok();
+ }
+}
+
+const InMemoryBookRepositoryImpl = BookRepository.createImplementation({
+ implementation: InMemoryBookRepository,
+ dependencies: []
+});
+
+export default InMemoryBookRepositoryImpl;
+```
+
+### With Dependencies
+
+Dependencies are declared in the constructor and must match the `dependencies` array order:
+
+```typescript
+import { CreateBookUseCase } from "./abstractions/CreateBookUseCase.js";
+import { BookRepository } from "./abstractions/BookRepository.js";
+import { AuthorRepository } from "./abstractions/AuthorRepository.js";
+import { CategoryRepository } from "./abstractions/CategoryRepository.js";
+import { Result } from "webiny/api";
+
+class CreateBookUseCaseImpl implements CreateBookUseCase.Interface {
+ public constructor(
+ private bookRepository: BookRepository.Interface,
+ private authorRepository: AuthorRepository.Interface,
+ private categoryRepository: CategoryRepository.Interface
+ ) {}
+
+ public async execute(input: CreateBookUseCase.Input): CreateBookUseCase.Return {
+ const authorResult = await this.authorRepository.getById(input.authorId);
+ if (authorResult.isFail()) {
+ return authorResult;
+ }
+
+ const categoryResult = await this.categoryRepository.getById(input.categoryId);
+ if (categoryResult.isFail()) {
+ return categoryResult;
+ }
+
+ const book: CreateBookUseCase.Book = {
+ id: generateId(),
+ title: input.title,
+ author: authorResult.value,
+ category: categoryResult.value
+ };
+
+ const saveResult = await this.bookRepository.save(book);
+ if (saveResult.isFail()) {
+ return saveResult;
+ }
+
+ return Result.ok(book);
+ }
+}
+
+const CreateBookUseCaseImplementation = CreateBookUseCase.createImplementation({
+ implementation: CreateBookUseCaseImpl,
+ dependencies: [BookRepository, AuthorRepository, CategoryRepository]
+});
+
+export default CreateBookUseCaseImplementation;
+```
+
+## Using Decorators
+
+Decorators extend behavior without modifying the original implementation. Use `createDecorator()` from the abstraction to wrap existing functionality:
+
+```typescript
+import { CreateBookUseCase } from "./abstractions/CreateBookUseCase.js";
+import { Logger } from "webiny/api/logger";
+
+class LoggingCreateBookDecorator implements CreateBookUseCase.Interface {
+ public constructor(
+ private logger: Logger.Interface,
+ private decoratee: CreateBookUseCase.Interface
+ ) {}
+
+ public async execute(input: CreateBookUseCase.Input): CreateBookUseCase.Return {
+ this.logger.info("Creating book", { title: input.title });
+
+ const result = await this.decoratee.execute(input);
+
+ if (result.isOk()) {
+ this.logger.info("Book created successfully", { bookId: result.value.id });
+ } else {
+ this.logger.error("Failed to create book", { error: result.error });
+ }
+
+ return result;
+ }
+}
+
+const LoggingCreateBookDec = CreateBookUseCase.createDecorator({
+ decorator: LoggingCreateBookDecorator,
+ dependencies: [Logger]
+});
+
+export default LoggingCreateBookDec;
+```
+
+**Key Point:** The decorator's last constructor parameter must be the type being decorated. The `decoratee` is automatically injected - you only list other dependencies in the `dependencies` array.
+
+## Key Points
+
+### Dependency Order Matters
+
+The order in the `dependencies` array must exactly match the constructor parameter order:
+
+```typescript
+class MyClass implements SomeAbstraction.Interface {
+ public constructor(
+ private firstDep: FirstDep.Interface,
+ private secondDep: SecondDep.Interface
+ ) {}
+}
+
+const MyClassImpl = SomeAbstraction.createImplementation({
+ implementation: MyClass,
+ dependencies: [
+ FirstDep,
+ SecondDep
+ ]
+});
+```
+
+### Always Use .Interface Types
+
+Constructor parameters should use the `.Interface` type from the abstraction:
+
+```typescript
+// ✅ Correct
+public constructor(private bookRepository: BookRepository.Interface) {}
+
+// ❌ Wrong - don't use the concrete class
+public constructor(private bookRepository: InMemoryBookRepository) {}
+```
+
+### Export the Implementation
+
+Always export the result of `createImplementation()` or `createDecorator()`:
+
+```typescript
+const MyImplementation = Something.createImplementation({
+ implementation: SomethingImpl,
+ dependencies: []
+});
+
+export default MyImplementation;
+```
+
diff --git a/docs/developer-docs/6.0.x/basic/result.ai.txt b/docs/developer-docs/6.0.x/basic/result.ai.txt
new file mode 100644
index 000000000..9cbc86366
--- /dev/null
+++ b/docs/developer-docs/6.0.x/basic/result.ai.txt
@@ -0,0 +1,121 @@
+AI Context: Result Pattern (result.mdx)
+
+Source of Information:
+1. Analyzed existing code examples throughout the 6.0.x documentation
+2. Observed Result pattern usage in event handlers, use cases, and repositories
+3. Examined the Result class API from code examples showing:
+ - Result.ok() for success
+ - Result.fail() for errors
+ - isOk() and isFail() methods
+ - error and value properties
+4. Studied the pattern across multiple files (entry.mdx, model.mdx, group.mdx event handlers)
+
+Understanding the Result Pattern:
+The Result pattern is an alternative to try/catch for error handling. Instead of throwing exceptions, functions return a Result object that contains either a success value or an error value. Think of it like a box that always tells you "did this work?" before you open it.
+
+Why Use Result Pattern:
+- Type Safety: TypeScript knows exactly what errors can happen
+- Explicit: Must check for errors (can't forget to handle them)
+- No Surprises: No hidden exceptions that crash your app
+- Better Flow: Read code top-to-bottom, no try/catch blocks
+
+Key Documentation Decisions:
+- Explain the pattern's purpose: type-safe error handling without exceptions
+- Show both success and failure paths
+- Demonstrate property access patterns (value, error)
+- Include checking methods (isOk(), isFail())
+- Show async usage patterns (commonly used throughout)
+- Use simple, generic examples
+- Reference the pattern in DI context since they're used together
+
+Pattern Observed:
+```typescript
+// Step 1: Call a function that returns Result
+const result = await someOperation();
+
+// Step 2: Check if it failed (always do this first!)
+if (result.isFail()) {
+ return result; // or handle error: result.error contains the error
+}
+
+// Step 3: If we get here, it succeeded - safe to use the value
+const value = result.value;
+```
+
+How Result Works in Practice:
+- Use cases return Result
+- Repositories return Result or Result
+- Event handlers can return Result for validation/authorization
+- Enables functional error handling without try/catch
+
+Comparison with Try/Catch:
+```typescript
+// Traditional try/catch approach
+try {
+ const user = await createUser(data);
+ console.log(user);
+} catch (error) {
+ console.error(error);
+}
+
+// Result pattern approach
+const result = await createUser(data);
+if (result.isFail()) {
+ console.error(result.error);
+ return;
+}
+console.log(result.value);
+```
+
+Common Pattern - Early Return on Failure:
+```typescript
+async function processData() {
+ const result1 = await step1();
+ if (result1.isFail()) return result1; // Stop if failed
+
+ const result2 = await step2(result1.value);
+ if (result2.isFail()) return result2; // Stop if failed
+
+ return Result.ok(result2.value); // All steps succeeded
+}
+```
+
+Related Documents:
+- See basic/di.mdx for how Result integrates with DI
+- See all use-case/*.mdx files for Result usage examples
+- See all event-handler/*.mdx files for validation patterns
+
+Key Code Locations:
+- Result class: @webiny/feature/api (look for Result import in examples)
+- Usage examples: Throughout the codebase showing Result pattern
+
+To examine source code implementations in detail, access to the Webiny project repository is needed.
+
+Common Patterns to Follow:
+1. Always check isFail() before accessing value
+2. Return failed results early (guard clauses)
+3. Use Result.ok(value) for success
+4. Use Result.fail(error) for failures
+5. Chain Results in async operations
+
+Code Pattern to Follow:
+```typescript
+const result = await someOperation();
+if (result.isFail()) {
+ return result; // propagate error
+}
+const data = result.value; // safe to access
+```
+
+Tone Guidelines:
+- Explain WHY Result pattern is used (type safety, explicit errors)
+- Show both success and failure paths
+- Keep examples simple and clear
+
+Key Takeaways:
+1. Result = A container that holds either success value OR error
+2. Always check isFail() before using result.value
+3. No try/catch needed - errors are explicit in the return type
+4. TypeScript helps: it knows what errors can happen
+5. Pattern used consistently: use cases, repositories, event handlers
+
diff --git a/docs/developer-docs/6.0.x/basic/result.mdx b/docs/developer-docs/6.0.x/basic/result.mdx
new file mode 100644
index 000000000..bc2a69825
--- /dev/null
+++ b/docs/developer-docs/6.0.x/basic/result.mdx
@@ -0,0 +1,147 @@
+---
+id: bpki4nn3
+title: Result
+description: About Result
+---
+
+import {Alert} from "@/components/Alert";
+
+
+
+- What is the `Result`?
+- How to use it?
+- How to use the return types?
+
+
+
+## Overview
+
+System is utilizing the `Result` pattern, and there is a `Result` class that helps with that.
+
+The `Result` pattern is a way to represent the outcome of an operation that can either succeed or fail.
+Instead of throwing exceptions, functions return a `Result` object that encapsulates either a successful value or an error.
+
+## Usage
+
+Let's say you have a function that performs some async call to an operation which you import from a dependency, and it can either return a result or throw an error.
+
+```typescript
+import {Result} from "webiny/api";
+import {someOperation} from "some-module";
+
+const myMethod = async() => {
+ try {
+ const operationResult = await someOperation();
+ return Result.ok(operationResult);
+ } catch(ex) {
+ return Result.fail(ex);
+ }
+}
+const result = await myMethod();
+if(result.isOk()) {
+ console.log("Operation succeeded with value:", result.value);
+} else {
+ console.error("Operation failed with error:", result.error);
+}
+```
+
+This way you can be sure that the method does not throw an exception, and you do not have to worry about it down the call stack, which uses the `myMethod` function.
+
+## Return Types
+
+When using the `Result` pattern the return types are inferred from the values passed to the `Result.ok()` and `Result.fail()` methods.
+
+For example, if you have a function that returns a `Result` object with a successful value of type `string` and an error of type `Error`, the return type would be `Result`.
+
+```typescript
+import {Result} from "webiny/api";
+const myMethod = async(): Promise> => {
+ try {
+ const operationResult = await someOperation();
+ return Result.ok(operationResult);
+ } catch(ex) {
+ return Result.fail(ex);
+ }
+}
+```
+
+For more complex return types, you can define custom types for the success value and error value.
+
+```typescript
+import type { Result } from "webiny/api";
+import type { NotAuthorizedError, ValueNotFoundError } from "webiny/api/error";
+
+export interface SuccessData {
+ id: string;
+ name: string;
+}
+export interface Success {
+ data: SuccessData;
+ timestamp: number;
+}
+interface PossibleErrors {
+ notFound: ValueNotFoundError;
+ notAuthorized: NotAuthorizedError;
+}
+
+type MyMethodErrors = PossibleErrors[keyof PossibleErrors];
+
+type ReturnOfTheMethod = Promise>;
+
+interface MyMethodParams {
+ id: string;
+}
+
+export interface MyMethod {
+ (params: MyMethodParams): ReturnOfTheMethod;
+}
+```
+
+And then you can implement the method like this:
+
+```typescript
+import { Result } from "webiny/api";
+
+const myMethod: MyMethod = async (params) => {
+ try {
+ const operationResult = await someOperation(params.id);
+ if (!operationResult) {
+ return Result.fail(new ValueNotFoundError(`Value with ID ${params.id} not found.`));
+ }
+ const successData: SuccessData = {
+ id: operationResult.id,
+ name: operationResult.name,
+ };
+ return Result.ok({
+ data: successData,
+ timestamp: Date.now(),
+ });
+ } catch (ex) {
+ return Result.fail(new NotAuthorizedError(`Not authorized to access value with ID ${params.id}.`));
+ }
+};
+```
+
+## Result Unwrap
+
+When using methods and functions that return a `Result` object, you might want to get the actual value or error types from the `Result` object.
+
+If the type is not available for you to import, you can use the `Result.UnwrapResult` and `Result.UnwrapError` utility to get those types.
+
+For example, using the `GetEntryByIdUseCase` from Headless CMS:
+
+```typescript
+import type { Result } from "webiny/api";
+import type { GetEntryByIdUseCase } from "webiny/api/cms/entry";
+
+export type IGetEntryByIdValue = Result.UnwrapResult;
+export type IGetEntryByIdError = Result.UnwrapError;
+```
+
+This can be useful when you want to use return types from the system through your own code, but the types are not directly available for import.
+
+
+## Conclusion
+The `Result` pattern is a powerful way to handle success and failure in your code without relying on exceptions.
+By using the `Result` class, you can create functions that return a `Result` object, making it easier to manage errors and success values in a consistent manner.
+Additionally, the ability to infer return types from the `Result` object allows for better type safety and clarity in your code.
diff --git a/docs/developer-docs/6.0.x/cli/deploy.ai.txt b/docs/developer-docs/6.0.x/cli/deploy.ai.txt
new file mode 100644
index 000000000..8f378a5a9
--- /dev/null
+++ b/docs/developer-docs/6.0.x/cli/deploy.ai.txt
@@ -0,0 +1,35 @@
+AI Context: CLI - webiny deploy (cli/deploy.mdx)
+
+Source of Information:
+1. v5 docs: https://www.webiny.com/docs/core-development-concepts/basics/project-deployment
+2. v5 docs: https://www.webiny.com/docs/core-development-concepts/basics/webiny-cli
+3. Existing v6 doc patterns (tasks/about.mdx, graphql/about.mdx)
+
+Key Documentation Decisions:
+- Placed in cli/ root group, not under reference/ — these are operational command docs, not API reference
+- Kept v5 content but stripped screenshots and external links to Pulumi docs
+- No shell/bash code blocks per convention — using plain fenced blocks without language tag for CLI commands
+- Removed v5-specific mention of four apps (Core/API/Admin/Website) as canonical project structure may differ in v6
+- Kept the dependency ordering note as it is still accurate and practically important
+- Troubleshooting section trimmed to two most common issues; full Pulumi state repair deferred to pulumi.mdx
+
+Command Signature:
+ yarn webiny deploy [APP_PATH] --env ENV [--debug]
+
+Behavior:
+- Without APP_PATH: deploys all apps in order (Core → API → Admin → Website)
+- With APP_PATH: deploys only that app; --env is required
+- Builds code first (runs build script from webiny.config.ts per package)
+- Uses Pulumi under the hood; --debug exposes raw Pulumi error output
+
+Related Documents:
+- cli/destroy.mdx — tear down what deploy created
+- cli/pulumi.mdx — raw Pulumi command access
+- cli/output.mdx — read stack outputs after deploy
+- cli/watch.mdx — incremental dev-time redeploy
+
+Tone Guidelines:
+- Direct and operational — this is a command reference page
+- Show the command first, explain after
+- No marketing language
+- Warnings only for genuinely dangerous or surprising behavior (20-min first deploy, dependency order)
diff --git a/docs/developer-docs/6.0.x/cli/deploy.mdx b/docs/developer-docs/6.0.x/cli/deploy.mdx
new file mode 100644
index 000000000..27fffbc92
--- /dev/null
+++ b/docs/developer-docs/6.0.x/cli/deploy.mdx
@@ -0,0 +1,63 @@
+---
+id: wn4bx7k2
+title: webiny deploy
+description: Build and deploy your Webiny project to AWS.
+---
+
+import { Alert } from "@/components/Alert";
+
+
+
+- How to deploy your whole Webiny project
+- How to deploy one or more specific apps
+- What options the `deploy` command accepts
+
+
+
+## Overview
+
+The `deploy` command builds your code and deploys the resulting cloud infrastructure to AWS using Pulumi. You can deploy the whole project at once, or target one or more specific apps.
+
+## Deploy the Whole Project
+
+```
+yarn webiny deploy
+```
+
+This deploys all apps in the correct order. The environment defaults to `dev`. To target a different environment:
+
+```
+yarn webiny deploy --env prod
+```
+
+
+ Depending on your [database setup](#), the first deployment can take up to 20 minutes.
+
+
+## Deploy Specific Apps
+
+Pass one or more app names as arguments:
+
+```
+yarn webiny deploy api
+yarn webiny deploy core api
+yarn webiny deploy core api admin
+```
+
+With a specific environment:
+
+```
+yarn webiny deploy api --env prod
+```
+
+## Options
+
+| Option | Description |
+| --------------------------- | ----------------------------------------------------------------------------------- |
+| `--env` | Environment name (e.g. `dev`, `prod`). Defaults to `dev`. |
+| `--variant` | Variant name. |
+| `--region` | AWS region to target. |
+| `--build` | Build packages before deploying. Defaults to `true`. |
+| `--preview` | Preview the deploy without actually performing it. |
+| `--show-deployment-logs` | Print deployment logs (automatically enabled in CI). |
+| `--allow-local-state-files` | Allow using local Pulumi state files with production deployments (not recommended). |
diff --git a/docs/developer-docs/6.0.x/cli/destroy.ai.txt b/docs/developer-docs/6.0.x/cli/destroy.ai.txt
new file mode 100644
index 000000000..2a1a3e566
--- /dev/null
+++ b/docs/developer-docs/6.0.x/cli/destroy.ai.txt
@@ -0,0 +1,31 @@
+AI Context: CLI - webiny destroy (cli/destroy.mdx)
+
+Source of Information:
+1. v5 docs: https://www.webiny.com/docs/infrastructure/basics/destroy-cloud-infrastructure
+2. v5 docs: https://www.webiny.com/docs/core-development-concepts/basics/webiny-cli
+
+Key Documentation Decisions:
+- Placed in cli/ root group alongside deploy, watch, output, pulumi
+- Leading warning about irreversibility — this is a destructive command
+- Reverse-order teardown note is critical for users who try to destroy Core before API
+- Protected resources section kept because prod-environment protection trips up users regularly
+- PreconditionFailed troubleshooting points to `webiny pulumi` for the refresh command rather than raw Pulumi CLI
+- OpenSearch timing note retained — users frequently think something has gone wrong
+
+Command Signature:
+ yarn webiny destroy [APP_PATH] --env ENV [--confirm-destroy-env ENV] [--debug]
+
+Behavior:
+- APP_PATH required for single-app destroy; --env always required
+- No APP_PATH: destroys all apps; must also pass --confirm-destroy-env matching --env
+- Pulumi protect: true resources in prod will block destroy until protection is lifted
+- --debug exposes raw Pulumi logs
+
+Related Documents:
+- cli/deploy.mdx — creates what destroy removes
+- cli/pulumi.mdx — used for state repair (refresh, stack export/import)
+
+Tone Guidelines:
+- Direct and cautious — lead with the warning
+- Operational: show the commands, explain the caveats
+- No filler prose
diff --git a/docs/developer-docs/6.0.x/cli/destroy.mdx b/docs/developer-docs/6.0.x/cli/destroy.mdx
new file mode 100644
index 000000000..c45c6dee1
--- /dev/null
+++ b/docs/developer-docs/6.0.x/cli/destroy.mdx
@@ -0,0 +1,59 @@
+---
+id: qm3tz9hs
+title: webiny destroy
+description: Destroy cloud infrastructure previously deployed for a Webiny app.
+---
+
+import { Alert } from "@/components/Alert";
+
+
+
+- How to destroy cloud infrastructure for a single app
+- How to fully destroy your whole Webiny project
+
+
+
+## Overview
+
+The `destroy` command removes all cloud infrastructure resources previously deployed by [`webiny deploy`](/docs/cli/deploy) for a given app and environment. It delegates to Pulumi internally.
+
+
+ This operation is irreversible. All AWS resources managed by the specified Pulumi stack will be
+ permanently deleted.
+
+
+## Destroy the Whole Project
+
+```
+yarn webiny destroy
+```
+
+The environment defaults to `dev`. To target a different environment:
+
+```
+yarn webiny destroy --env prod
+```
+
+## Destroy a Single App
+
+Pass the app name as the first argument:
+
+```
+yarn webiny destroy api
+yarn webiny destroy admin
+yarn webiny destroy core
+```
+
+With a specific environment:
+
+```
+yarn webiny destroy api --env prod
+```
+
+## Options
+
+| Option | Description |
+| ----------- | --------------------------------------------------------- |
+| `--env` | Environment name (e.g. `dev`, `prod`). Defaults to `dev`. |
+| `--variant` | Variant name. |
+| `--region` | AWS region to target. |
diff --git a/docs/developer-docs/6.0.x/cli/info.ai.txt b/docs/developer-docs/6.0.x/cli/info.ai.txt
new file mode 100644
index 000000000..17e9d474b
--- /dev/null
+++ b/docs/developer-docs/6.0.x/cli/info.ai.txt
@@ -0,0 +1,24 @@
+AI Context: CLI - webiny info (cli/info.mdx)
+
+Source of Information:
+1. webiny info --help output from wby-next project
+2. v5 docs: https://www.webiny.com/docs/core-development-concepts/basics/webiny-cli
+
+Key Documentation Decisions:
+- Very short page — the command has no subcommands, one job, few options
+- Framed as "quick reference without AWS console" — that's the practical use case
+- No screenshot (v5 had one); keeping it text-only per v6 doc conventions
+
+Command Signature:
+ yarn webiny info [--env ENV] [--variant VARIANT] [--region REGION]
+
+Behavior:
+- Reads deployed stack outputs and prints URLs (Admin, API endpoint, etc.)
+- Read-only, no side effects
+
+Related Documents:
+- cli/output.mdx — more detailed stack output inspection
+- cli/deploy.mdx — deploys the project whose URLs info displays
+
+Tone Guidelines:
+- Very concise — one-liner overview, usage, options table
diff --git a/docs/developer-docs/6.0.x/cli/info.mdx b/docs/developer-docs/6.0.x/cli/info.mdx
new file mode 100644
index 000000000..334f4d463
--- /dev/null
+++ b/docs/developer-docs/6.0.x/cli/info.mdx
@@ -0,0 +1,37 @@
+---
+id: mn7qr3pb
+title: webiny info
+description: List relevant URLs for your deployed Webiny project.
+---
+
+import { Alert } from "@/components/Alert";
+
+
+
+- How to quickly retrieve URLs for your deployed Webiny project
+
+
+
+## Overview
+
+The `info` command prints relevant URLs for your deployed Webiny project — things like the Admin app URL and the API endpoint. Useful when you need a quick reference without opening the AWS console.
+
+## Usage
+
+```
+yarn webiny info
+```
+
+With a specific environment:
+
+```
+yarn webiny info --env prod
+```
+
+## Options
+
+| Option | Description |
+| ----------- | --------------------------------------------------------- |
+| `--env` | Environment name (e.g. `dev`, `prod`). Defaults to `dev`. |
+| `--variant` | Variant name. |
+| `--region` | AWS region to target. |
diff --git a/docs/developer-docs/6.0.x/cli/output.ai.txt b/docs/developer-docs/6.0.x/cli/output.ai.txt
new file mode 100644
index 000000000..dc7c2ac5f
--- /dev/null
+++ b/docs/developer-docs/6.0.x/cli/output.ai.txt
@@ -0,0 +1,28 @@
+AI Context: CLI - webiny output (cli/output.mdx)
+
+Source of Information:
+1. v5 docs: https://www.webiny.com/docs/core-development-concepts/basics/webiny-cli (output section)
+2. General Pulumi stack output concept
+
+Key Documentation Decisions:
+- Short page — the command is simple, no need to pad it
+- Focus on "what is it for" (retrieving deployment artifacts without AWS console) and "what does it print"
+- Listed common output values as examples rather than exhaustive spec, since actual outputs vary by app version
+- JSON output note added — useful for scripting use cases (CI/CD pipelines reading outputs)
+
+Command Signature:
+ yarn webiny output APP_PATH --env ENV
+
+Behavior:
+- Reads the Pulumi stack state and prints exported output values as JSON
+- Does not redeploy or modify anything — read-only
+- Both APP_PATH and --env are required
+
+Related Documents:
+- cli/deploy.mdx — creates the stack whose outputs this command reads
+- cli/pulumi.mdx — for more advanced stack inspection via raw Pulumi commands
+
+Tone Guidelines:
+- Concise — this is a small utility command
+- Practical framing: "you need this when you want X without going to the AWS console"
+- No filler
diff --git a/docs/developer-docs/6.0.x/cli/output.mdx b/docs/developer-docs/6.0.x/cli/output.mdx
new file mode 100644
index 000000000..9c841efae
--- /dev/null
+++ b/docs/developer-docs/6.0.x/cli/output.mdx
@@ -0,0 +1,52 @@
+---
+id: hc5np2dw
+title: webiny output
+description: Print the Pulumi stack output for a deployed Webiny app.
+---
+
+import { Alert } from "@/components/Alert";
+
+
+
+- How to read stack output values for a deployed app
+- What kind of information the output command returns
+
+
+
+## Overview
+
+The `output` command prints the Pulumi stack output for an app that has already been deployed. Stack outputs are values that the infrastructure code explicitly exports — things like API endpoint URLs, CloudFront distribution IDs, S3 bucket names, and similar deployment artifacts.
+
+This is useful when you need to retrieve a URL or resource identifier after deployment without opening the AWS console.
+
+## Usage
+
+```
+yarn webiny output api
+yarn webiny output core
+yarn webiny output admin
+```
+
+With a specific environment:
+
+```
+yarn webiny output api --env prod
+```
+
+## Options
+
+| Option | Description |
+| ----------- | --------------------------------------------------------- |
+| `--env` | Environment name (e.g. `dev`, `prod`). Defaults to `dev`. |
+| `--variant` | Variant of the app. |
+| `--region` | AWS region to target. |
+| `--json` | Emit output as JSON. |
+
+## What Gets Printed
+
+The exact outputs depend on what each app exports from its Pulumi program. Common values include:
+
+- API GraphQL endpoint URL
+- CloudFront distribution domain names
+- Cognito User Pool and Client IDs
+- S3 bucket names
diff --git a/docs/developer-docs/6.0.x/cli/pulumi.ai.txt b/docs/developer-docs/6.0.x/cli/pulumi.ai.txt
new file mode 100644
index 000000000..2a5983cd4
--- /dev/null
+++ b/docs/developer-docs/6.0.x/cli/pulumi.ai.txt
@@ -0,0 +1,35 @@
+AI Context: CLI - webiny pulumi (cli/pulumi.mdx)
+
+Source of Information:
+1. v5 docs: https://www.webiny.com/docs/infrastructure/pulumi-iac/execute-pulumi-commands
+2. v5 docs: https://www.webiny.com/docs/core-development-concepts/basics/webiny-cli
+
+Key Documentation Decisions:
+- Positioned as an escape hatch / advanced tool, not a daily driver — most users never need it
+- The `--` separator is easy to miss and causes confusing errors; it gets its own callout in the usage section
+- Focused on the three most common real-world use cases: resource inspection, stuck stack repair, refresh
+- Dropped the v5 FAQ question about which CLI to prefer — obvious answer is always use Webiny CLI; not worth the space
+- Local Pulumi binary location mentioned once for debugging purposes
+- --yes flag troubleshooting kept — this trips up CI/CD pipelines regularly
+
+Command Signature:
+ yarn webiny pulumi APP_PATH --env ENV -- [pulumi-args]
+
+Behavior:
+- Sets up env vars and selects the correct Pulumi stack automatically
+- Passes everything after `--` verbatim to the embedded Pulumi CLI
+- Runs in non-interactive mode; confirmations require --yes
+
+Related Documents:
+- cli/deploy.mdx — uses Pulumi internally; use this for normal deployments
+- cli/destroy.mdx — uses Pulumi internally; mentions pulumi for state repair
+- cli/output.mdx — simpler alternative for reading stack outputs
+
+Key Code Locations:
+- node_modules/@webiny/pulumi-sdk/pulumi — embedded Pulumi binary
+- packages/pulumi-sdk in webiny-js monorepo — source of the wrapper
+
+Tone Guidelines:
+- Technical and concise
+- Show real commands, not abstract placeholders
+- Frame it as "you need this when X" for each use case
diff --git a/docs/developer-docs/6.0.x/cli/pulumi.mdx b/docs/developer-docs/6.0.x/cli/pulumi.mdx
new file mode 100644
index 000000000..b0a0abfc9
--- /dev/null
+++ b/docs/developer-docs/6.0.x/cli/pulumi.mdx
@@ -0,0 +1,91 @@
+---
+id: xt6kp4nj
+title: webiny pulumi
+description: Execute Pulumi CLI commands against a Webiny app stack.
+---
+
+import { Alert } from "@/components/Alert";
+
+
+
+- When and why you need to run raw Pulumi commands
+- How to use `webiny pulumi` to pass commands to the Pulumi CLI
+- Common scenarios where this command is required
+
+
+
+## Overview
+
+The `pulumi` command is a thin wrapper that lets you run any [Pulumi CLI](https://www.pulumi.com/docs/reference/cli/) command against a specific app and environment. Webiny embeds its own Pulumi binary and sets up the required environment variables automatically — you do not need to install Pulumi separately or select a stack manually.
+
+Most day-to-day work uses [`webiny deploy`](/docs/cli/deploy) and [`webiny destroy`](/docs/cli/destroy). Use `webiny pulumi` when you need lower-level access that those commands do not expose.
+
+## Usage
+
+The app name and the `--` separator are both required. Everything after `--` is passed directly to the Pulumi CLI.
+
+```
+yarn webiny pulumi api --
+```
+
+With a specific environment:
+
+```
+yarn webiny pulumi api --env prod --
+```
+
+## Options
+
+| Option | Description |
+| ----------- | --------------------------------------------------------- |
+| `--env` | Environment name (e.g. `dev`, `prod`). Defaults to `dev`. |
+| `--variant` | Variant name. |
+| `--region` | AWS region to target. |
+
+## Common Use Cases
+
+### Inspect Stack Resources
+
+List all cloud infrastructure resources currently tracked in the stack:
+
+```
+yarn webiny pulumi api -- stack --show-urns
+```
+
+### Repair a Stuck Stack (Pending Operations)
+
+If a deployment was interrupted, Pulumi may report resources stuck in a `pending_operations` state. Export the stack, edit it to remove the pending entries, then import it back:
+
+```
+yarn webiny pulumi api -- stack export --file stack.json
+# edit stack.json — remove entries from "pending_operations"
+yarn webiny pulumi api -- stack import --file stack.json
+```
+
+### Refresh State
+
+Sync the Pulumi state file with the actual state of resources in AWS:
+
+```
+yarn webiny pulumi api -- refresh --yes
+```
+
+This is useful when resources have been modified outside of Pulumi (e.g. manually in the AWS console).
+
+### Preview Changes
+
+See what `deploy` would change without actually deploying:
+
+```
+yarn webiny pulumi api -- preview
+```
+
+## Troubleshooting
+
+### `--yes must be passed in to proceed when running in non-interactive mode`
+
+Webiny runs all Pulumi commands in non-interactive mode. If a Pulumi command requires confirmation, add `--yes`:
+
+```
+yarn webiny pulumi api -- destroy --yes
+```
diff --git a/docs/developer-docs/6.0.x/cli/watch.ai.txt b/docs/developer-docs/6.0.x/cli/watch.ai.txt
new file mode 100644
index 000000000..bf85a670e
--- /dev/null
+++ b/docs/developer-docs/6.0.x/cli/watch.ai.txt
@@ -0,0 +1,28 @@
+AI Context: CLI - webiny watch (cli/watch.mdx)
+
+Source of Information:
+1. v5 docs: https://www.webiny.com/docs/core-development-concepts/basics/watch-command
+2. v5 docs: https://www.webiny.com/docs/core-development-concepts/basics/webiny-cli
+
+Key Documentation Decisions:
+- Kept the frontend vs. backend split as the key conceptual distinction — most user confusion comes from expecting a local server for the API
+- Dropped the v5 "Can I Use This?" availability notice (v5.5.0+) — not relevant to v6 docs
+- Dropped the v5 beta "New Watch Command" callout about local Lambda development — v6 may handle this differently; don't carry over beta notes without verification
+- Kept the "API must be deployed first" note — this is a real gotcha for new users
+- FAQ trimmed to the single most important question (can I run locally)
+
+Command Signature:
+ yarn webiny watch APP_PATH --env ENV
+
+Behavior:
+- Frontend (admin, website): local dev server + hot reload; requires API already deployed
+- Backend (api): file watcher → build → Lambda redeploy cycle; no local server
+
+Related Documents:
+- cli/deploy.mdx — initial deployment before watch can be used for backend
+- cli/output.mdx — retrieve URLs after deploy to use during watch sessions
+
+Tone Guidelines:
+- Practical and direct
+- Explain the frontend/backend difference clearly — it surprises users
+- Keep it short; the command has limited options
diff --git a/docs/developer-docs/6.0.x/cli/watch.mdx b/docs/developer-docs/6.0.x/cli/watch.mdx
new file mode 100644
index 000000000..f74f7bc06
--- /dev/null
+++ b/docs/developer-docs/6.0.x/cli/watch.mdx
@@ -0,0 +1,83 @@
+---
+id: bv8mr1yx
+title: webiny watch
+description: Start a local development session with continuous rebuild and redeploy.
+---
+
+import { Alert } from "@/components/Alert";
+
+
+
+- How to use `webiny watch` for frontend and backend development
+- How the command behaves differently for `api` vs. `admin`
+- How Local AWS Lambda Development works
+
+
+
+## Overview
+
+The `watch` command is the primary tool for active development on a Webiny project. It monitors your source files for changes and continuously rebuilds and redeploys your code, so you don't need to manually run `webiny deploy` after every edit.
+
+The command works differently depending on which app you are watching.
+
+## Usage
+
+```
+yarn webiny watch api
+yarn webiny watch admin
+```
+
+With a specific environment:
+
+```
+yarn webiny watch api --env prod
+```
+
+## Options
+
+| Option | Description |
+| --------------------- | -------------------------------------------------------------------------- |
+| `--env` | Environment name (e.g. `dev`, `prod`). Defaults to `dev`. |
+| `--variant` | Variant name. |
+| `--region` | AWS region to target. |
+| `-p, --package` | One or more packages to watch for code changes. |
+| `--allow-production` | Enables running `watch` against production environments (not recommended). |
+| `--deployment-checks` | Enable or disable deployment checks before watching. Defaults to `true`. |
+
+### Local AWS Lambda Development Options
+
+| Option | Description |
+| ------------------------------ | ------------------------------------------------------------------- |
+| `-f, --function` | One or more Lambda functions to watch (comma-separated). |
+| `--increase-timeout` | Increase Lambda function timeout in seconds. Defaults to `120`. |
+| `--increase-handshake-timeout` | Increase the initial handshake timeout in seconds. Defaults to `5`. |
+| `-i, --inspect` | [Experimental] Enable Node debugger. |
+
+## How It Works
+
+### Frontend App (Admin)
+
+For the **Admin** app, `watch` spins up a local development server. The app is rebuilt and hot-reloaded in the browser whenever a source file changes.
+
+### Backend App (API) — Local AWS Lambda Development
+
+For the **API** app, `watch` uses Local AWS Lambda Development. Your Lambda code runs on your local machine while staying connected to real AWS infrastructure — DynamoDB, OpenSearch, S3, Cognito, and other services your project depends on.
+
+Here's what happens when you run `yarn webiny watch api`:
+
+- **Lambda stubs are deployed** — Webiny's Lambda functions are temporarily replaced with stub code that forwards incoming events to your local machine.
+- **Requests are forwarded locally** — when a request hits AWS, the stub forwards it to your local process.
+- **Your code runs locally** — with the full Lambda execution context (environment variables, function context, etc.).
+- **Responses are routed back** — your local response travels back through the stub to the original caller.
+
+This means you can iterate on backend code and see results immediately, without waiting for a full deployment. You can also attach a debugger since the code runs locally.
+
+
+ When you stop `watch`, your Lambda functions still contain stub code — your API will not work
+ until you redeploy. Run `yarn webiny deploy api` to restore the actual Lambda code. The watch
+ command will remind you of this when it exits.
+
+
+### Why Not Run Everything Locally?
+
+Running AWS-managed services like DynamoDB, OpenSearch, and Cognito fully locally would be complex and unreliable. The hybrid approach — local code execution, real cloud services — gives you fast iteration with a realistic environment.
diff --git a/docs/developer-docs/6.0.x/get-started/install-webiny.mdx b/docs/developer-docs/6.0.x/get-started/install-webiny.mdx
new file mode 100644
index 000000000..7c245e443
--- /dev/null
+++ b/docs/developer-docs/6.0.x/get-started/install-webiny.mdx
@@ -0,0 +1,76 @@
+---
+id: aafeab3f
+title: Install Webiny
+description: Learn how to create a new Webiny project and deploy it into your AWS account.
+---
+
+import { Alert } from "@/components/Alert";
+import { TabsComponent, TabsItem } from "@/components/TabsComponent";
+
+
+
+ - how to create a brand new Webiny project
+ - how to deploy it to your [AWS](https://aws.amazon.com/) account
+
+
+
+---
+
+## Prerequisites
+
+Before proceeding, make sure you have the following:
+
+1. **Node.js >=22**
+- Node.js versions **22** or greater
+- If you don't have Node.js installed, the easiest way to install it is by [downloading the official binary](https://nodejs.org/en/)
+2. **yarn**
+- Webiny works with both yarn versions [1 (classic)](https://yarnpkg.com/en/docs/install) and [>=2 (berry)](https://yarnpkg.com/)
+- for version 1 - **1.22.0** or later is required
+3. **AWS account and user credentials**
+- in order to deploy Webiny, you must have a valid [AWS account and user credentials](/docs/infrastructure/aws/configure-aws-credentials) set up on your system
+
+## Project Setup
+
+Once you have all the prerequisites in place, we recommend creating a new Webiny project using `create-webiny-project` - a tool that sets everything up automatically for you. So, in your terminal of choice, run the following command:
+
+```
+npx create-webiny-project my-new-project
+```
+
+From there, follow the on-screen setup instructions, which includes answering a couple of project-related questions, and doing your first deployment.
+
+### Pick Your Database Setup
+
+Webiny supports two database setups:
+
+1. **Amazon DynamoDB** (for small and medium sized projects)
+2. **Amazon DynamoDB + Amazon OpenSearch** (for large / enterprise-level projects)
+
+If you're building a small project (couple of thousands of database records) or just giving Webiny a try, we suggest you go with the **Amazon DynamoDB** database setup. On the other hand, if you're building a larger project and you know you will be dealing with hundreds of thousands or even millions of database records, choose the **Amazon DynamoDB + Amazon OpenSearch** database setup.
+
+Please choose your database setup with consideration for both present and future project requirements. The decision you make at this point **cannot** be changed later on without recreating your project from scratch.
+
+#### Amazon DynamoDB + Amazon OpenSearch - Monthly Cost❗
+
+Although Webiny is designed to rely on serverless cloud infrastructure resources, the **Amazon DynamoDB + Amazon OpenSearch** database setup relies on [Amazon OpenSearch Service](https://aws.amazon.com/opensearch-service/), which is not serverless.
+
+More precisely, it doesn't scale to zero and it's billed per hour of usage. The cheapest configuration (which Webiny deploys for your development-related environments) amounts to roughly **$25/month**. For more information, please refer to the [Amazon OpenSearch Service pricing](https://aws.amazon.com/opensearch-service/pricing/) page.
+
+## First Deployment
+
+Once your new project has been created, it's time to deploy it into your AWS account. You can do that simply by running the following command in your terminal:
+
+```
+yarn webiny deploy
+```
+
+Note that the first deployment can take up to 15-30 minutes! So, even though it might look nothing is happening in the terminal, please be patient and let the process finish. If something went wrong, an error will be shown.
+
+Ultimately, once the deployment has been done, you are presented with the URL over which you can access your Admin Area, and finish the installation.
+
+
+
+ Running the `yarn webiny info` command in your Webiny project folder provide you with the needed information.
+
+
+
diff --git a/docs/developer-docs/6.0.x/get-started/welcome.mdx b/docs/developer-docs/6.0.x/get-started/welcome.mdx
new file mode 100644
index 000000000..a57e8a977
--- /dev/null
+++ b/docs/developer-docs/6.0.x/get-started/welcome.mdx
@@ -0,0 +1,78 @@
+---
+id: db45d287
+title: Welcome to Webiny Docs
+description: Learn how to install Webiny and customize its capabilities as a developer.
+pageHeader: false
+fullWidth: false
+---
+
+## Webiny Docs
+
+Welcome to the Webiny documentation — your reference manual for building, extending, and operating Webiny.
+
+Whether you’re integrating Webiny into an existing product, tailoring it into an enterprise content platform, or embedding it as a white-label builder, this portal is where you’ll find the exact methods, functions, and patterns you need.
+
+---
+
+## What is Webiny?
+
+Webiny is an open-source, self-hosted content platform that combines ready-made apps (like Headless CMS, Website Builder, File Manager/DAM, Publishing Workflows, and Tenant Manager) with a TypeScript framework and APIs you can extend. You get SaaS-like reliability on a serverless foundation — but deployed into **your** cloud, under **your** governance.
+
+Webiny is built for teams that want flexibility without lock-in: define models and business rules as code, hook into lifecycle events, automate workflows, and integrate with any frontend or internal systems.
+
+---
+
+## How to use the docs
+
+The docs are organized into three sections:
+
+**Getting Started**
+Install Webiny, run it locally, deploy to your cloud, and learn the core building blocks.
+
+**Guides**
+Step-by-step tutorials for real projects: extending apps, adding custom logic, integrating SSO, automating publishing, building multi-tenant setups, embedding the page builder, and more.
+
+**API Reference**
+The detailed technical reference: functions, methods, types, GraphQL operations, lifecycle events, background tasks, and extension points.
+
+Use the sidebar to navigate, or search (Ctrl+K / Cmd+K) to jump straight to what you need.
+
+---
+
+## Webiny apps and “framework mode”
+
+Webiny has two complementary ways to work:
+
+**Apps (ready-made products)**
+Use Webiny’s built-in applications like Headless CMS, Website Builder, File Manager, Publishing Workflows, and Tenant Manager. They come with UI, permissions, editorial tooling, and the defaults most teams need.
+
+**Framework mode (build your own)**
+Treat Webiny as your programmable foundation: add modules, extend APIs, create custom screens, enforce business rules, and shape workflows around your organization — all in a way that stays maintainable and upgrade-safe.
+
+---
+
+## Prerequisite knowledge
+
+This documentation assumes you’re comfortable with:
+
+* JavaScript / TypeScript
+* Modern web development fundamentals
+* GraphQL basics
+* Node.js tooling
+
+If you’re new to GraphQL or TypeScript, start with the Getting Started section and follow the examples as you go.
+
+---
+
+## Where to start
+
+The best place to start learning Webiny is to go through the **Learn Webiny Course**. It’s a free, self-paced course that takes you through the basics of installing Webiny, running it locally, and deploying it to the cloud. You can find the course at learn.webiny.com/.
+
+
+---
+
+## Join the Webiny community
+
+If you get stuck, want feedback on an architecture, or need help with an extension, the community and the team are close by. You can also reach out if you want a technical deep-dive for your specific project. Join Webiny Community.
+
+
diff --git a/docs/developer-docs/6.0.x/graphql/about.ai.txt b/docs/developer-docs/6.0.x/graphql/about.ai.txt
new file mode 100644
index 000000000..d2ccccb82
--- /dev/null
+++ b/docs/developer-docs/6.0.x/graphql/about.ai.txt
@@ -0,0 +1,63 @@
+AI Context: GraphQL - About (graphql/about.mdx)
+
+Source of Information:
+1. Read graphql/reference.mdx and graphql/example.mdx to understand implementation
+2. Analyzed the GraphQL schema factory pattern used in the system
+3. Examined type and resolver registration patterns
+4. Understood the declarative schema building approach
+
+Understanding the Factory Pattern:
+The system uses a factory pattern for building GraphQL schemas. Instead of writing SDL (Schema Definition Language) strings or using decorators, you call factory methods to register types and resolvers.
+
+The Factory Approach vs Traditional:
+- Traditional: Schema-first (SDL strings) or code-first (decorators)
+- Factory Pattern: Programmatic, modular registration
+- Benefits: Type safety, modularity, extensibility, schema composition
+
+Key Documentation Decisions:
+- Created introductory document explaining GraphQL integration
+- Focused on the factory pattern approach (not traditional schema-first or code-first)
+- Explained the declarative nature of schema building
+- Described the two main components: types and resolvers
+- Kept it conceptual rather than implementation-focused
+- Made it accessible for developers new to this GraphQL approach
+- Linked to example and reference docs for implementation details
+
+Document Structure:
+- Overview: How GraphQL works in this system
+- What You'll Learn
+- Factory Pattern explanation
+- Types and Resolvers concepts
+- Why this approach (modularity, extensibility, type safety)
+- Links to practical examples
+
+Factory Pattern Components:
+1. Types - Object types, inputs, enums, interfaces
+2. Resolvers - Query/mutation/field logic
+3. Schema building - Declarative registration
+
+Key Concepts:
+- GraphQL schema factory pattern
+- Type definitions (objects, inputs, enums)
+- Resolvers for fields and queries/mutations
+- Declarative schema building
+- Modularity and extensibility benefits
+
+Key Benefits:
+- Type safety with TypeScript
+- Modular schema building
+- Easy extension without schema conflicts
+- Integration with DI container
+- Separation of concerns
+
+Related Documents:
+- graphql/reference.mdx - Factory API methods
+- graphql/example.mdx - Complete working examples
+- All use-case/*.mdx files show resolver integration
+
+Tone Guidelines:
+- Conceptual introduction
+- Compare to familiar approaches (Apollo, TypeGraphQL, schema-first, code-first)
+- Explain the "why" of factory pattern
+- Link to practical examples
+
diff --git a/docs/developer-docs/6.0.x/graphql/about.mdx b/docs/developer-docs/6.0.x/graphql/about.mdx
new file mode 100644
index 000000000..3113d25bd
--- /dev/null
+++ b/docs/developer-docs/6.0.x/graphql/about.mdx
@@ -0,0 +1,30 @@
+---
+id: a6cd5pa6
+title: About
+description: About GraphQL
+---
+
+import {Alert} from "@/components/Alert";
+
+
+
+- How system uses GraphQL for its API layer?
+- What is the GraphQL Schema Factory pattern?
+- How to extend and customize GraphQL schemas?
+
+
+
+## Overview
+
+System uses GraphQL as its primary API layer for all core applications including Headless CMS, Website Builder, and File Manager. GraphQL provides a flexible, type-safe way to query and mutate data, allowing clients to request exactly the data they need.
+
+### GraphQL Schema Factory
+
+System implements a factory pattern for building GraphQL schemas. The `GraphQLSchemaFactory` interface allows you to extend and customize the GraphQL API by:
+
+- **Adding type definitions** - Define your own GraphQL types, inputs, queries, and mutations
+- **Registering resolvers** - Implement the logic that handles GraphQL operations
+- **Dependency injection** - Access services and use cases within your resolvers
+- **Modular architecture** - Build your schema in a composable, maintainable way
+
+This approach keeps your GraphQL layer thin and focused on data access, while business logic lives in dedicated service classes. You can extend existing schemas or create entirely new GraphQL APIs that integrate seamlessly with the system's infrastructure.
diff --git a/docs/developer-docs/6.0.x/graphql/example.ai.txt b/docs/developer-docs/6.0.x/graphql/example.ai.txt
new file mode 100644
index 000000000..978edd4fa
--- /dev/null
+++ b/docs/developer-docs/6.0.x/graphql/example.ai.txt
@@ -0,0 +1,97 @@
+AI Context: GraphQL - Example (graphql/example.mdx)
+
+Source of Information:
+1. Analyzed code examples showing GraphQL type resolver and schema definition implementation
+2. Examined the factory pattern for type and resolver registration
+3. Studied the integration between GraphQL types and business logic
+4. Reviewed the modular approach to schema building
+
+Key Documentation Decisions:
+- Provide a complete, working example of GraphQL implementation
+- Show both type definitions and resolver implementations
+- Demonstrate the factory pattern in action
+- Include query and mutation examples
+- Show how to integrate with use cases/business logic
+- Make it practical and copy-paste friendly
+- Used a cohesive example (Book management system)
+
+Example Structure:
+1. Type Definitions - BookType with fields
+2. Input Types - CreateBookInput for mutations
+3. Query Resolvers - getBook, listBooks
+4. Mutation Resolvers - createBook, updateBook
+5. Integration with use cases
+
+Pattern Demonstrated:
+- factory.createObjectType() for types
+- factory.createInputObjectType() for inputs
+- factory.createResolver() for query/mutation logic
+- Type-safe resolver implementations
+- Integration with domain layer (use cases)
+- Error handling with Result pattern
+
+Tone: Practical and example-driven, showing how all pieces fit together. Maintains technical accuracy and consistency with reference.mdx.
+
+Related Documents:
+- graphql/reference.mdx - Factory API methods
+- graphql/about.mdx - Conceptual overview
+- All use-case/*.mdx files show integration with GraphQL resolvers
+
+GraphQL Factory Pattern to Follow:
+```typescript
+// 1. Define types
+factory.createObjectType({
+ name: "Book",
+ fields: {
+ id: { type: "ID!" },
+ title: { type: "String!" },
+ author: { type: "Author" }
+ }
+});
+
+// 2. Define inputs
+factory.createInputObjectType({
+ name: "CreateBookInput",
+ fields: {
+ title: { type: "String!" },
+ authorId: { type: "ID!" }
+ }
+});
+
+// 3. Create resolvers
+factory.createResolver({
+ type: "Query",
+ field: "getBook",
+ resolve: async (source, args, context) => {
+ const useCase = context.get(GetBookUseCase);
+ const result = await useCase.execute(args.id);
+
+ if (result.isFail()) {
+ throw new Error(result.error.message);
+ }
+
+ return result.value;
+ }
+});
+```
+
+Common Patterns:
+1. Type definitions separate from resolvers
+2. Use Input types for mutations
+3. Integrate with use cases in resolvers
+4. Handle Result pattern in resolvers (convert to errors/values)
+5. Use context.get() for dependency injection
+6. Type field definitions carefully (! for required)
+
+Integration with Use Cases:
+- Resolvers are thin layers
+- Business logic in use cases
+- Resolvers handle GraphQL-specific concerns
+- Use cases handle domain logic
+
+Tone Guidelines:
+- Show complete, working examples
+- Explain integration points
+- Match reference.mdx tone
+- Use "The system provides" consistently
+
diff --git a/docs/developer-docs/6.0.x/graphql/example.mdx b/docs/developer-docs/6.0.x/graphql/example.mdx
new file mode 100644
index 000000000..9f5f3a082
--- /dev/null
+++ b/docs/developer-docs/6.0.x/graphql/example.mdx
@@ -0,0 +1,204 @@
+---
+id: ba8s58we
+title: Example
+description: GraphQL Example
+---
+
+import {Alert} from "@/components/Alert";
+
+
+
+- How to add your own GraphQL schema?
+- How to define GraphQL types, inputs, and mutations?
+- How to add resolvers with dependency injection?
+- How to handle errors in GraphQL responses?
+- How to extend existing GraphQL types?
+
+
+
+## Overview
+
+System provides a powerful GraphQL API framework that allows you to extend and customize the GraphQL schema. By implementing the `GraphQLSchemaFactory` interface, you can add custom types, queries, and mutations to your application.
+
+The example demonstrates a complete implementation of a custom GraphQL query that lists CMS entries from any content model. It shows how to:
+
+- Define GraphQL type definitions using `addTypeDefs()` with custom types and response structures
+- Extend existing GraphQL types (like `Query`) with your custom operations
+- Add resolvers using `addResolver()` with dependency injection support
+- Handle both success and error responses using the Result pattern
+
+This pattern follow clean architecture principles, keeping the GraphQL layer thin and delegating business logic to dedicated use cases. The resolver functions receive injected dependencies and handle the communication between the GraphQL API and your application services.
+
+
+## Query Code Example
+
+```typescript
+import { GraphQLSchemaFactory } from "webiny/api/graphql";
+import { GetModelUseCase } from "webiny/api/cms/model";
+import { ListPublishedEntriesUseCase } from "webiny/api/cms/entry";
+
+interface IListCmsEntriesArgs {
+ modelId: string;
+ limit?: number;
+ after?: string;
+}
+
+class ListCmsEntriesGraphQL implements GraphQLSchemaFactory.Interface {
+ public async execute(builder: GraphQLSchemaFactory.SchemaBuilder): GraphQLSchemaFactory.Return {
+ builder.addTypeDefs(/* GraphQL */ `
+ type CustomListCmsEntriesResponseItem {
+ id: ID!
+ title: String!
+ }
+ type CustomListCmsEntriesResponse {
+ data: [CustomListCmsEntriesResponseItem!]
+ meta: CmsListMeta
+ error: CmsError
+ }
+
+ extend type Query {
+ listCmsEntries(
+ modelId: ID!
+ limit: Int
+ after: String
+ ): CustomListCmsEntriesResponse!
+ }
+ `);
+
+ builder.addResolver({
+ path: "Query.listCmsEntries",
+ dependencies: [GetModelUseCase, ListPublishedEntriesUseCase],
+ resolver(
+ getModel: GetModelUseCase.Interface,
+ listEntries: ListPublishedEntriesUseCase.Interface
+ ) {
+ return async ({ args }) => {
+ const { modelId, limit, after } = args;
+
+ const modelResult = await getModel.execute(modelId);
+
+ if (modelResult.isFail()) {
+ return {
+ error: modelResult.error,
+ data: null,
+ meta: null
+ };
+ }
+ const model = modelResult.value;
+
+ const entriesResult = await listEntries.execute(model, {
+ limit: limit || 10,
+ after: after || null
+ });
+ if (entriesResult.isFail()) {
+ return {
+ error: entriesResult.error,
+ data: null,
+ meta: null
+ };
+ }
+
+ const { entries, meta } = entriesResult.value;
+
+ return {
+ data: entries.map(item => ({
+ id: item.id,
+ title: item.values[model.titleFieldId] || "No title"
+ })),
+ meta,
+ error: null
+ };
+ };
+ }
+ });
+
+ return builder;
+ }
+}
+
+export default GraphQLSchemaFactory.createImplementation({
+ implementation: ListCmsEntriesGraphQL,
+ dependencies: [],
+});
+```
+
+
+## Mutation Code Example
+
+```typescript
+import { GraphQLSchemaFactory } from "webiny/api/graphql";
+import { GetModelUseCase } from "webiny/api/cms/model";
+import { CreateEntryUseCase } from "webiny/api/cms/entry";
+
+interface ILogMyClickArgs {
+ id: string;
+ ip: string;
+}
+
+class LogMyClickGraphQL implements GraphQLSchemaFactory.Interface {
+ public async execute(builder: GraphQLSchemaFactory.SchemaBuilder): GraphQLSchemaFactory.Return {
+ builder.addTypeDefs(/* GraphQL */ `
+ type LogMyClickResponseItem {
+ id: ID!
+ ip: String!
+ createdOn: String!
+ }
+ type LogMyClickResponse {
+ data: LogMyClickResponseItem
+ error: CmsError
+ }
+
+ extend type Mutation {
+ logMyClick(id: ID!, ip: String!): LogMyClickResponse!
+ }
+ `);
+
+ builder.addResolver({
+ path: "Mutation.logMyClick",
+ dependencies: [GetModelUseCase, CreateEntryUseCase],
+ resolver(
+ getModel: GetModelUseCase.Interface,
+ createEntry: CreateEntryUseCase.Interface
+ ) {
+ return async ({ args }) => {
+ const modelResult = await getModel.execute("logMyClickModel");
+
+ if (modelResult.isFail()) {
+ return {
+ error: modelResult.error,
+ data: null,
+ meta: null
+ };
+ }
+ const model = modelResult.value;
+
+ const result = await createEntry.execute(model, {
+ values: {
+ id: args.id,
+ ip: args.ip
+ }
+ });
+ if (result.isFail()) {
+ return {
+ error: result.error,
+ data: null,
+ meta: null
+ };
+ }
+ return {
+ data: result.value,
+ error: null
+ };
+ };
+ }
+ });
+
+ return builder;
+ }
+}
+
+export default GraphQLSchemaFactory.createImplementation({
+ implementation: LogMyClickGraphQL,
+ dependencies: [],
+});
+```
diff --git a/docs/developer-docs/6.0.x/graphql/reference.ai.txt b/docs/developer-docs/6.0.x/graphql/reference.ai.txt
new file mode 100644
index 000000000..c1c08f7a9
--- /dev/null
+++ b/docs/developer-docs/6.0.x/graphql/reference.ai.txt
@@ -0,0 +1,93 @@
+AI Context: GraphQL - Reference (graphql/reference.mdx)
+
+Source of Information:
+1. Analyzed GraphQL schema factory code examples
+2. Examined factory methods for creating types, inputs, and resolvers
+3. Studied the API surface of the GraphQL factory
+4. Understood the type registration and schema building process
+
+Key Documentation Decisions:
+- Simple, concise reference documentation
+- Focus on the factory API methods
+- Document each factory method (createObjectType, createInputObjectType, createResolver)
+- Show method signatures and options
+- Keep examples minimal but illustrative
+- Explain when to use each method
+- Cross-reference with example.mdx for complete implementations
+
+Methods Documented:
+1. createObjectType() - Define GraphQL object types
+2. createInputObjectType() - Define input types for mutations
+3. createResolver() - Implement query/mutation logic
+4. Type system integration
+
+Overview Written:
+- Explains that factory provides declarative API
+- Describes type safety benefits
+- Notes the modular nature
+- Keeps it simple and to-the-point
+
+Pattern Observed:
+- Factory pattern for schema building
+- Type definitions separate from resolvers
+- Declarative API design
+- Integration with TypeScript for type safety
+
+Tone: Consistent reference documentation style, technical and concise.
+
+Related Documents:
+- graphql/about.mdx - Conceptual overview
+- graphql/example.mdx - Complete examples
+
+Factory Methods to Document:
+1. createObjectType() - Define GraphQL object types
+2. createInputObjectType() - Define input types
+3. createResolver() - Implement query/mutation logic
+
+Method Signatures:
+```typescript
+// Object Type
+factory.createObjectType({
+ name: "TypeName",
+ fields: {
+ fieldName: { type: "String!" },
+ relation: { type: "RelatedType" }
+ }
+});
+
+// Input Type
+factory.createInputObjectType({
+ name: "InputName",
+ fields: {
+ fieldName: { type: "String!" }
+ }
+});
+
+// Resolver
+factory.createResolver({
+ type: "Query" | "Mutation",
+ field: "fieldName",
+ resolve: async (source, args, context) => {
+ // resolver logic
+ }
+});
+```
+
+Type System Notes:
+- Use "!" for required fields
+- Reference other types by name (string)
+- Support for scalars, objects, lists
+- TypeScript type safety
+
+Common Patterns:
+1. Define types first
+2. Create inputs for mutations
+3. Implement resolvers separately
+4. Use context for dependencies
+
+Tone Guidelines:
+- Reference documentation style
+- Simple, concise examples
+- Focus on API surface
+- Link to example.mdx for complete implementations
+
diff --git a/docs/developer-docs/6.0.x/graphql/reference.mdx b/docs/developer-docs/6.0.x/graphql/reference.mdx
new file mode 100644
index 000000000..e289f9f59
--- /dev/null
+++ b/docs/developer-docs/6.0.x/graphql/reference.mdx
@@ -0,0 +1,54 @@
+---
+id: y3o2fsfu
+title: Reference
+description: GraphQL Reference
+---
+
+
+import {Alert} from "@/components/Alert";
+
+
+
+- How to add your own GraphQL queries?
+- How to add type definitions to the schema?
+- How to register resolvers with the path-based approach?
+
+
+
+## Overview
+
+This reference shows the basic structure of implementing a GraphQL Schema Factory. The `GraphQLSchemaFactory` interface provides two key methods: `addTypeDefs()` to define your GraphQL types, and `addResolver()` to handle the resolution logic. The resolver configuration requires specifying the path to the GraphQL type, any dependencies needed, and the resolver function itself.
+
+## Code Example
+
+```typescript
+import { GraphQLSchemaFactory } from "webiny/api/graphql";
+
+class GraphQLReference implements GraphQLSchemaFactory.Interface {
+ public async execute(builder: GraphQLSchemaFactory.SchemaBuilder): GraphQLSchemaFactory.Return {
+ builder.addTypeDefs(/* GraphQL */ `
+ type MyCustomQuery {
+ somePath: String
+ }
+ `);
+
+ builder.addResolver({
+ // path to target graphql schema type
+ path: "MyCustomQuery.somePath",
+ // an array containing all the dependencies required by the resolver
+ dependencies: [],
+ // function that returns the resolver function and receives the dependencies as arguments
+ resolver: (...dependenciesInOrderTheyWereAssigned) => {
+ return async ({parent, context, info, args}) => {
+ return "Hello World!";
+ };
+ }
+ });
+
+ return builder;
+ }
+}
+
+export default GraphQLReference;
+
+```
diff --git a/docs/developer-docs/6.0.x/headless-cms/about.ai.txt b/docs/developer-docs/6.0.x/headless-cms/about.ai.txt
new file mode 100644
index 000000000..cd79ba49d
--- /dev/null
+++ b/docs/developer-docs/6.0.x/headless-cms/about.ai.txt
@@ -0,0 +1,81 @@
+AI Context: Headless CMS - About (headless-cms/about.mdx)
+
+Source of Information:
+1. Analyzed all headless-cms documentation files created
+2. Examined the architecture: models, groups, entries
+3. Studied the builder, event handler, and use case patterns
+4. Understood the overall CMS extension architecture
+
+Key Documentation Decisions:
+- Created overview document for the entire Headless CMS section
+- Explained the three-tier architecture (models, groups, entries)
+- Introduced the main extension points (builders, event handlers, use cases)
+- Provided navigation to detailed documentation
+- Made it accessible for developers new to extending the CMS
+- Explained when and why to extend each component
+
+Document Structure:
+- Overview: What is extensible in Headless CMS
+- What You'll Learn
+- Architecture explanation (Models → Groups → Entries)
+- Extension points:
+ - Builders (define structure)
+ - Event Handlers (react to changes)
+ - Use Cases (custom business logic)
+- Links to detailed documentation sections
+
+Key Concepts:
+- Content models define structure
+- Groups organize models
+- Entries are content instances
+- Builders create definitions
+- Event handlers add behavior
+- Use cases implement custom logic
+
+Related Documents:
+- headless-cms/builder/*.mdx - Creating models/groups/fields
+- headless-cms/event-handler/*.mdx - Reacting to lifecycle events
+- headless-cms/use-case/*.mdx - Custom business logic
+- headless-cms/examples/*.mdx - Practical examples
+- headless-cms/ui/*.mdx - Admin UI customization
+
+CMS Architecture (Three-Tier):
+1. Groups - Organizational containers for models
+2. Models - Content structure definitions (like database tables)
+3. Entries - Content instances (like database rows)
+
+Extension Points:
+1. Builders - Programmatically define structure
+ - GroupBuilder: Create groups
+ - ModelBuilder: Create models
+ - FieldBuilder: Define fields
+
+2. Event Handlers - React to lifecycle events
+ - Before/After Create, Update, Delete
+ - Validation, authorization, side effects
+
+3. Use Cases - Custom business logic
+ - Override default behavior
+ - Add custom operations
+ - Implement workflows
+
+Document Structure:
+- Overview of extensibility
+- What You'll Learn
+- Architecture explanation (Groups → Models → Entries)
+- Extension points overview
+- Links to detailed documentation
+
+Navigation Guide:
+- Want to create models? → builder/*.mdx
+- Want to add validation? → event-handler/*.mdx
+- Want custom logic? → use-case/*.mdx
+- Want UI changes? → ui/*.mdx
+- Need examples? → examples/*.mdx
+
+Tone Guidelines:
+- High-level architectural overview
+- Guide to detailed documentation
+- Help developers choose right approach
+- Explain relationships between components
+
diff --git a/docs/developer-docs/6.0.x/headless-cms/about.mdx b/docs/developer-docs/6.0.x/headless-cms/about.mdx
new file mode 100644
index 000000000..17caf27f0
--- /dev/null
+++ b/docs/developer-docs/6.0.x/headless-cms/about.mdx
@@ -0,0 +1,40 @@
+---
+id: 3mhdm3qu
+title: About
+description: About Headless CMS
+---
+
+import {Alert} from "@/components/Alert";
+
+
+
+- What are the core extensibility points in Headless CMS?
+- How models, groups, and entries work together?
+- When to use builders, event handlers, and use cases?
+
+
+
+## Overview
+
+The Headless CMS is built around three core concepts: **Groups**, **Models**, and **Entries**. Groups organize related models, models define content structure, and entries are the actual content instances.
+
+### Extension Points
+
+You can extend the Headless CMS through three main approaches:
+
+**Builders** - Programmatically define structure using:
+- `GroupBuilder` - Create and organize model groups
+- `ModelBuilder` - Define content models
+- `FieldBuilder` - Configure model fields
+
+**Event Handlers** - React to lifecycle events:
+- Before/After Create, Update, Delete operations
+- Validation and authorization hooks
+- Custom business logic integration
+
+**Use Cases** - Implement custom business logic:
+- Override default behavior
+- Add custom operations
+- Implement complex workflows
+
+For detailed documentation on each extension point, see the specific sections on [Builders](/docs/headless-cms/builder), [Event Handlers](/docs/headless-cms/event-handler), and [Use Cases](/docs/headless-cms/use-case).
diff --git a/docs/developer-docs/6.0.x/headless-cms/builder/field.ai.txt b/docs/developer-docs/6.0.x/headless-cms/builder/field.ai.txt
new file mode 100644
index 000000000..1daa32321
--- /dev/null
+++ b/docs/developer-docs/6.0.x/headless-cms/builder/field.ai.txt
@@ -0,0 +1,118 @@
+AI Context: Field Builder (headless-cms/builder/field.mdx)
+
+Source of Information:
+1. Examined field builder code in package source files
+2. Analyzed available field builder methods and options
+3. Reviewed field type definitions and configuration
+4. Studied the field settings and validation patterns
+5. Cross-referenced with field-renderer.mdx for UI integration
+
+Key Documentation Decisions:
+- Document the field builder API comprehensively
+- Show all available field methods
+- Explain field types (text, number, boolean, datetime, object, ref, etc.)
+- Detail configuration options (required, multiple values, validation)
+- Include field settings (predefinedValues, renderer configuration)
+- Link to field renderer documentation for UI customization
+- Provide practical examples for each field type
+- Explain when to use each field type
+
+Field Types Documented:
+1. Basic Types - text, longText, number, boolean
+2. Date/Time - datetime with timezone support
+3. Rich Content - richText
+4. References - ref (model references)
+5. Object - nested objects
+6. File - file uploads
+
+Field Configuration:
+- Field ID and label
+- Required validation
+- Multiple values support
+- Predefined values (select options)
+- Custom validation rules
+- Default values
+- Help text
+- Renderer settings for UI
+
+Pattern Observed:
+- Fluent API for field building
+- Method chaining for configuration
+- Type-safe field definitions
+- Integration with UI renderers
+- Validation at field level
+
+Related Documents:
+- headless-cms/builder/model.mdx - Model builder (uses fields)
+- headless-cms/ui/field-renderer.mdx - UI renderers for fields
+- headless-cms/builder/group.mdx - Group organization
+
+Key Code Locations:
+- Field builder: packages/api-headless-cms/src/features/modelBuilder
+- Field types: packages/api-headless-cms/src/features/modelBuilder
+
+To examine source code implementations in detail, access to the Webiny project repository is needed.
+
+Field Builder Pattern:
+```typescript
+model.field()
+ .id("title")
+ .label("Title")
+ .type("text")
+ .required(true)
+ .help("Enter the title");
+```
+
+Field Types to Document:
+1. Basic: text, longText, number, boolean
+2. Date/Time: datetime (with timezone support via settings.type)
+3. Rich: richText
+4. Relations: ref (model references)
+5. Structured: object (nested)
+6. Media: file
+
+Field Configuration Methods:
+- id(string) - Unique field identifier
+- label(string) - Display label
+- type(string) - Field type
+- required(boolean) - Validation
+- list() - Array values
+- predefinedValues(array) - Select options
+- help(string) - User guidance
+- placeholder(string) - Input placeholder
+- description(string) - Field description
+- defaultValue(any) - Default
+- validation(rules) - Custom validation
+- renderer(config) - UI renderer settings
+
+Special Configurations:
+- DateTime: Requires settings.type = "date" | "time" | "dateTimeWithTimezone" | "dateTimeWithoutTimezone"
+- Ref: Requires settings.models for which models to reference
+- Object: Requires settings.fields for nested structure
+
+Example Patterns:
+```typescript
+// Simple text field
+.field().id("name").label("Name").type("text").required(true)
+
+// Multiple values
+.field().list().id("tags").label("Tags").type("text")
+
+// With predefined values
+.field().id("status").label("Status").type("text")
+ .predefinedValues([
+ { value: "draft", label: "Draft" },
+ { value: "published", label: "Published" }
+ ])
+
+// DateTime with timezone
+.field().id("publishedAt").label("Published").type("datetime")
+ .settings({ type: "dateTimeWithTimezone" })
+```
+
+Tone Guidelines:
+- Technical reference style
+- Complete method documentation
+- Show practical examples for each type
+- Link to field-renderer.mdx for UI customization
+
diff --git a/docs/developer-docs/6.0.x/headless-cms/builder/field.mdx b/docs/developer-docs/6.0.x/headless-cms/builder/field.mdx
new file mode 100644
index 000000000..cab7f2d2f
--- /dev/null
+++ b/docs/developer-docs/6.0.x/headless-cms/builder/field.mdx
@@ -0,0 +1,347 @@
+---
+id: b2t5ocpx
+title: Field Builder
+description: About Field Builder in the Headless CMS Model Builder
+---
+
+import {Alert} from "@/components/Alert";
+
+
+
+- How to use the Field Builder to define content model fields
+- What methods are available for configuring fields
+- How to apply validators to different field types
+- How to configure field renderers
+
+
+
+## Overview
+
+The Field Builder provides a fluent API for defining fields in content models. Each field type has specific methods for configuration and validation. Fields are created using the registry methods (e.g., `text()`, `number()`, etc.) and configured using chainable methods.
+
+## Common Methods
+
+All field types share these common configuration methods:
+
+**`label(text: string)`** - Sets the field label displayed in the UI.
+
+**`description(text: string)`** - Sets description text shown below the field label.
+
+**`note(text: string)`** - Sets a note shown below the field.
+
+**`help(text: string)`** - Sets help text shown in the tooltip next to the field label.
+
+**`placeholder(text: string)`** - Sets placeholder text for input fields.
+
+**`fieldId(id: string)`** - Sets the field identifier. Auto-generated from label if not specified.
+
+**`storageId(id: string)`** - Sets the storage identifier. Auto-generated if not specified.
+
+**`defaultValue(value: any)`** - Sets the default value for the field.
+
+**`list()`** - Marks the field as supporting multiple values.
+
+**`tags(tags: string[])`** - Adds tags to the field for categorization.
+
+**`renderer(name: string, settings?: Record)`** - Sets the field renderer. See [Field Renderers](/docs/headless-cms/ui/field-renderer) for available renderers.
+
+**`settings(settings: Record)`** - Sets additional field settings.
+
+**`predefinedValues(values: Array<{label: string, value: any, selected?: boolean}>)`** - Defines predefined values for the field (enables select boxes, radio buttons, or checkboxes).
+
+### List Validators
+
+When a field is marked with `.list()`, these validators become available:
+
+**`listMinLength(value: number, message?: string)`** - Minimum number of items required in the list.
+
+**`listMaxLength(value: number, message?: string)`** - Maximum number of items allowed in the list.
+
+## Boolean Field
+
+**Registry Method:** `boolean()`
+
+Boolean fields represent true/false values.
+
+### Methods
+
+**`defaultValue(value: boolean)`** - Sets the default boolean value.
+
+### Example
+
+```typescript
+title: "Published",
+field: registry.boolean()
+ .label("Published")
+ .description("Is this content published?")
+ .defaultValue(false)
+```
+
+## Text Field
+
+**Registry Method:** `text()`
+
+Text fields store short text values.
+
+### Validators
+
+**`required(message?: string)`** - Makes the field required.
+
+**`minLength(value: number, message?: string)`** - Minimum text length.
+
+**`maxLength(value: number, message?: string)`** - Maximum text length.
+
+**`pattern(regex: string, flags?: string, message?: string)`** - Custom regex pattern validation.
+
+**`email(message?: string)`** - Validates as email address.
+
+**`url(message?: string)`** - Validates as URL.
+
+**`lowerCase(message?: string)`** - Allows only lowercase characters.
+
+**`upperCase(message?: string)`** - Allows only uppercase characters.
+
+**`lowerCaseSpace(message?: string)`** - Allows only lowercase characters and spaces.
+
+**`upperCaseSpace(message?: string)`** - Allows only uppercase characters and spaces.
+
+**`unique(message?: string)`** - Ensures the value is unique across all entries.
+
+### Example
+
+```typescript
+title: "Email",
+field: registry.text()
+ .label("Email Address")
+ .placeholder("user@example.com")
+ .required()
+ .email()
+ .unique()
+```
+
+## Number Field
+
+**Registry Method:** `number()`
+
+Number fields store numeric values.
+
+### Validators
+
+**`required(message?: string)`** - Makes the field required.
+
+**`gte(value: number, message?: string)`** - Greater than or equal to validation.
+
+**`lte(value: number, message?: string)`** - Less than or equal to validation.
+
+### Example
+
+```typescript
+price: registry.number()
+ .label("Price")
+ .required()
+ .gte(0, "Price must be positive")
+ .lte(10000, "Price cannot exceed 10000")
+```
+
+## Long Text Field
+
+**Registry Method:** `longText()`
+
+Long text fields store larger amounts of text.
+
+### Validators
+
+Same validators as Text Field: `required`, `minLength`, `maxLength`, `pattern`, `email`, `url`, `lowerCase`, `upperCase`, `lowerCaseSpace`, `upperCaseSpace`.
+
+### Example
+
+```typescript
+description: registry.longText()
+ .label("Description")
+ .placeholder("Enter a detailed description...")
+ .maxLength(5000)
+```
+
+## Rich Text Field
+
+**Registry Method:** `richText()`
+
+Rich text fields store formatted content using the Lexical editor.
+
+### Validators
+
+**`required(message?: string)`** - Makes the field required.
+
+### Example
+
+```typescript
+content: registry.richText()
+ .label("Content")
+ .required()
+```
+
+## DateTime Field
+
+**Registry Method:** `datetime()`
+
+DateTime fields store date and time values in various formats.
+
+### Methods
+
+**`dateTimeType(type: DateTimeType)`** - Sets the datetime type. Types: `"date"`, `"time"`, `"dateTimeWithTimezone"`, `"dateTimeWithoutTimezone"`.
+
+**`dateOnly()`** - Shortcut for date-only fields.
+
+**`timeOnly()`** - Shortcut for time-only fields.
+
+**`withTimezone()`** - Shortcut for datetime with timezone.
+
+**`withoutTimezone()`** - Shortcut for datetime without timezone.
+
+### Validators
+
+**`required(message?: string)`** - Makes the field required.
+
+**`dateGte(value: string, message?: string)`** - Date must be greater than or equal to the specified date.
+
+**`dateLte(value: string, message?: string)`** - Date must be less than or equal to the specified date.
+
+### Example
+
+```typescript
+publishedAt: registry.datetime()
+ .label("Published At")
+ .withTimezone()
+ .required()
+ .dateGte("2024-01-01T00:00:00Z", "Cannot be before 2024")
+```
+
+## Reference Field
+
+**Registry Method:** `ref()`
+
+Reference fields create relationships between content entries.
+
+### Methods
+
+**`models(models: Array<{modelId: string}>)`** - Specifies which models can be referenced.
+
+### Validators
+
+**`required(message?: string)`** - Makes the field required.
+
+**`listMinLength(value: number, message?: string)`** - For multiple references, minimum number required.
+
+**`listMaxLength(value: number, message?: string)`** - For multiple references, maximum number allowed.
+
+### Example
+
+```typescript
+author: registry.ref()
+ .label("Author")
+ .models([{ modelId: "author" }])
+ .required(),
+
+tags: registry.ref()
+ .label("Tags")
+ .list()
+ .models([{ modelId: "tag" }])
+ .listMinLength(1)
+ .listMaxLength(10)
+```
+
+## Object Field
+
+**Registry Method:** `object()`
+
+Object fields contain nested field structures.
+
+### Methods
+
+**`fields(builder: (registry) => Record)`** - Defines nested fields.
+
+**`layout(layout: string[][] | (builder) => void)`** - Defines the layout of nested fields.
+
+### Validators
+
+**`required(message?: string)`** - Makes the field required.
+
+### Example
+
+```typescript
+address: registry.object()
+ .label("Address")
+ .fields(registry => ({
+ street: registry.text().label("Street"),
+ city: registry.text().label("City"),
+ zipCode: registry.text().label("ZIP Code"),
+ country: registry.text().label("Country")
+ }))
+ .layout([
+ ["street"],
+ ["city", "zipCode"],
+ ["country"]
+ ])
+```
+
+## Dynamic Zone Field
+
+**Registry Method:** `dynamicZone()`
+
+Dynamic zone fields allow selecting from predefined templates.
+
+### Methods
+
+**`template(id: string, config: TemplateConfig)`** - Adds a template option.
+
+Template config properties:
+- `name: string` - Template display name
+- `gqlTypeName: string` - GraphQL type name for the template
+- `icon?: CmsIcon` - Icon for the template
+- `description?: string` - Template description
+- `fields: (registry) => Record` - Template fields
+- `layout?: string[][]` - Template field layout
+
+### Validators
+
+**`required(message?: string)`** - Makes the field required.
+
+### Example
+
+```typescript
+sections: registry.dynamicZone()
+ .label("Page Sections")
+ .list()
+ .template("hero", {
+ name: "Hero Section",
+ gqlTypeName: "HeroSection",
+ description: "Large hero banner",
+ fields: registry => ({
+ title: registry.text().label("Title").required(),
+ subtitle: registry.text().label("Subtitle"),
+ image: registry.file().label("Background Image")
+ }),
+ layout: [["title"], ["subtitle"], ["image"]]
+ })
+ .template("text", {
+ name: "Text Section",
+ gqlTypeName: "TextSection",
+ description: "Rich text content",
+ fields: registry => ({
+ content: registry.richText().label("Content").required()
+ }),
+ layout: [["content"]]
+ })
+```
+
+## Field Renderers
+
+Field renderers determine how fields are displayed in the UI. To specify a renderer:
+
+```typescript
+title: registry.text()
+ .label("Title")
+ .renderer("text-input")
+```
+
+For a complete list of available renderers and which fields they support, see the [Field Renderers](/docs/headless-cms/ui/field-renderer) documentation.
diff --git a/docs/developer-docs/6.0.x/headless-cms/builder/group.ai.txt b/docs/developer-docs/6.0.x/headless-cms/builder/group.ai.txt
new file mode 100644
index 000000000..8636753c1
--- /dev/null
+++ b/docs/developer-docs/6.0.x/headless-cms/builder/group.ai.txt
@@ -0,0 +1,89 @@
+AI Context: Group Builder (headless-cms/builder/group.mdx)
+
+Source of Information:
+1. Analyzed the code example in the document showing group builder usage
+2. Examined the GroupBuilder API and methods
+3. Understood group properties (id, name, description, icon, slug)
+4. Studied the builder pattern implementation
+
+Key Documentation Decisions:
+- Document the group builder API
+- Explain what groups are (organizational units for models)
+- Show how to create a group programmatically
+- Detail all available configuration methods
+- Provide practical examples
+- Write "What You'll Learn" section based on content
+- Write overview section based on the example
+
+Overview Content:
+- Explains that groups organize content models
+- Describes the builder pattern approach
+- Notes the available configuration options
+- References the complete example
+
+What You'll Learn:
+- How to create a group using GroupBuilder
+- How to configure group properties
+- How to set group metadata (name, description, icon)
+- How to define the group slug
+
+Group Properties Documented:
+- id() - Unique identifier
+- name() - Display name
+- description() - Group description
+- icon() - Icon identifier
+- slug() - URL-friendly identifier
+
+Pattern Observed:
+- Fluent API with method chaining
+- Builder pattern for group creation
+- Simple, focused API
+- Integration with model organization
+
+Related Documents:
+- headless-cms/builder/model.mdx - Models belong to groups
+- headless-cms/use-case/group.mdx - Group use cases
+- headless-cms/event-handler/group.mdx - Group events
+
+GroupBuilder Pattern:
+```typescript
+import { GroupBuilder } from "@webiny/api-headless-cms";
+
+const group = new GroupBuilder()
+ .id("blog")
+ .name("Blog")
+ .description("Blog-related content models")
+ .icon("article")
+ .slug("blog")
+ .build();
+```
+
+Methods to Document:
+- id(string) - Unique identifier
+- name(string) - Display name
+- description(string) - Group description
+- icon(string) - Icon identifier
+- slug(string) - URL-friendly identifier
+
+Group Purpose:
+- Organize related models together
+- UI organization in admin
+- Logical grouping (e.g., "Blog", "Products", "Settings")
+
+Common Group Examples:
+- "Blog" - Posts, categories, authors
+- "E-commerce" - Products, orders, customers
+- "Settings" - Configuration models
+
+Method Chaining:
+All methods return the builder instance for fluent API:
+```typescript
+builder.id("x").name("X").description("...").icon("...").slug("x")
+```
+
+Tone Guidelines:
+- Simple and focused (groups are straightforward)
+- Show complete example
+- Explain organizational purpose
+- Keep it concise
+
diff --git a/docs/developer-docs/6.0.x/headless-cms/builder/group.mdx b/docs/developer-docs/6.0.x/headless-cms/builder/group.mdx
new file mode 100644
index 000000000..115ed45f7
--- /dev/null
+++ b/docs/developer-docs/6.0.x/headless-cms/builder/group.mdx
@@ -0,0 +1,46 @@
+---
+id: jdfydvcp
+title: Group Builder
+description: About Headless CMS Group Builder
+---
+
+import {Alert} from "@/components/Alert";
+
+
+
+- How to create groups using the Group Builder?
+
+
+
+## Overview
+
+The Group Builder allows you to programmatically create code groups. Groups are used to organize and categorize your models, making it easier to manage and navigate through different types of content in the Admin UI.
+
+By implementing the `ModelGroupFactory` interface, you can define groups with icons, names, and slugs. This is particularly useful when you need to create groups dynamically or as part of a plugin or extension installation process.
+
+## Code Example
+
+```typescript
+import { ModelGroupFactory } from "webiny/api/cms/group";
+
+class MyCustomGroup implements ModelGroupFactory.Interface {
+ public async execute(): ModelGroupFactory.Return {
+ return [
+ {
+ icon: {
+ name: "myIcon",
+ type: "icon"
+ },
+ name: "A Group",
+ slug: "my-custom-group"
+ }
+ ];
+ }
+}
+
+export default ModelGroupFactory.createImplementation({
+ implementation: MyCustomGroup,
+ dependencies: []
+});
+```
+
diff --git a/docs/developer-docs/6.0.x/headless-cms/builder/model.ai.txt b/docs/developer-docs/6.0.x/headless-cms/builder/model.ai.txt
new file mode 100644
index 000000000..bd697794d
--- /dev/null
+++ b/docs/developer-docs/6.0.x/headless-cms/builder/model.ai.txt
@@ -0,0 +1,120 @@
+AI Context: Model Builder (headless-cms/builder/model.mdx)
+
+Source of Information:
+1. Analyzed the code example in the document showing model builder usage
+2. Examined the ModelBuilder API and methods
+3. Understood model properties and configuration
+4. Studied field addition and layout configuration
+5. Reviewed model types (regular, singleton, private)
+
+Key Documentation Decisions:
+- Document the model builder API comprehensively
+- Explain what models are (content structure definitions)
+- Show how to create models programmatically
+- Detail model configuration options
+- Explain field management
+- Cover layout configuration
+- Provide practical examples
+- Write "What You'll Learn" based on content
+- Write overview based on the example
+
+Overview Content:
+- Explains that models define content structure
+- Describes the builder pattern approach
+- Notes model types and configuration options
+- Shows field addition and layout setup
+
+What You'll Learn:
+- How to create a model using ModelBuilder
+- How to configure model properties
+- How to add fields to a model
+- How to define model layout
+
+Model Configuration Documented:
+- id(), name(), singularApiName(), pluralApiName()
+- description(), group()
+- Fields management (add, remove, order)
+- Layout configuration
+- Model types (singleton, private)
+- Access control settings
+
+Pattern Observed:
+- Fluent API with method chaining
+- Builder pattern for model creation
+- Integration with field builder
+- Layout and organization options
+
+Related Documents:
+- headless-cms/builder/field.mdx - Field definitions
+- headless-cms/builder/group.mdx - Group organization
+- headless-cms/use-case/model.mdx - Model use cases
+- headless-cms/event-handler/model.mdx - Model events
+- headless-cms/examples/*.mdx - Model examples (private, singleton)
+
+ModelBuilder Pattern:
+```typescript
+import { ModelBuilder, FieldBuilder } from "@webiny/api-headless-cms";
+
+const model = new ModelBuilder()
+ .id("blogPost")
+ .name("Blog Post")
+ .singularApiName("BlogPost")
+ .pluralApiName("BlogPosts")
+ .description("Blog articles")
+ .group("blog")
+ .field(
+ new FieldBuilder()
+ .id("title")
+ .label("Title")
+ .type("text")
+ .required(true)
+ )
+ .build();
+```
+
+Core Methods:
+- id(string) - Model identifier
+- name(string) - Display name
+- singularApiName(string) - GraphQL singular (e.g., "BlogPost")
+- pluralApiName(string) - GraphQL plural (e.g., "BlogPosts")
+- description(string) - Model description
+- group(string) - Group ID
+
+Field Management:
+- field(FieldBuilder) - Add field
+- fields(FieldBuilder[]) - Add multiple
+- removeField(id) - Remove field
+- updateField(id, config) - Modify field
+
+Model Types (via configuration):
+- Regular model (default) - Multiple entries
+- Singleton model - Single entry only
+- Private model - No public API
+
+Layout Configuration:
+- layout(config) - Define field layout/grouping in UI
+
+Common Patterns:
+```typescript
+// Regular model
+new ModelBuilder()
+ .id("article")
+ .singularApiName("Article")
+ .pluralApiName("Articles")
+ // ...fields
+
+// Singleton (see examples/single-entry-model.mdx)
+// Private (see examples/private-model.mdx)
+```
+
+API Name Conventions:
+- Must start with capital letter
+- PascalCase recommended
+- Singular vs Plural: BlogPost vs BlogPosts
+
+Tone Guidelines:
+- Complete builder documentation
+- Show field integration
+- Reference example docs for special types
+- Explain API naming importance
+
diff --git a/docs/developer-docs/6.0.x/headless-cms/builder/model.mdx b/docs/developer-docs/6.0.x/headless-cms/builder/model.mdx
new file mode 100644
index 000000000..c9c8bcf73
--- /dev/null
+++ b/docs/developer-docs/6.0.x/headless-cms/builder/model.mdx
@@ -0,0 +1,129 @@
+---
+id: mffn5ef2
+title: Model Builder
+description: About Headless CMS Model Builder
+---
+
+import {Alert} from "@/components/Alert";
+
+
+
+- How to create content models using the Model Builder?
+
+
+
+## Overview
+
+The Model Builder allows you to programmatically create content models. Instead of manually creating models through the Admin UI, you can define them in code, which is ideal for version control, automated deployments, and creating reusable model templates.
+
+By implementing the `ModelFactory` interface, you can define complete content models with their fields, layouts, API names, and relationships. The builder provides a fluent API that makes it easy to configure various field types (text, rich text, file, reference, etc...) and their properties. Models can be organized into groups and can reference other models to create complex content structures.
+
+This approach is particularly useful when you need to provision models as part of a plugin, extension, or during project setup, ensuring consistency across different tenants and environments.
+
+## Code Example
+
+```typescript
+import { ModelFactory } from "webiny/api/cms/model";
+import { ListGroupsUseCase } from "webiny/api/cms/group";
+
+class BlogImpl implements ModelFactory.Interface {
+ public constructor(private listGroupsUseCase: ListGroupsUseCase.Interface) {}
+
+ public async execute(builder: ModelFactory.Builder): ModelFactory.Return {
+ const groups = await this.listGroupsUseCase.execute();
+ if (groups.isFail()) {
+ throw new Error(`Could not load groups: ${groups.error.message}`);
+ }
+ const [group] = groups.value;
+
+ if (!group) {
+ throw new Error(`At least one group must exist to create models.`);
+ }
+
+ return [
+ builder
+ .public({
+ name: "Category",
+ modelId: "category",
+ group: group.slug,
+ singularApiName: "Category",
+ pluralApiName: "Categories"
+ })
+ .description("A model used to categorize articles.")
+ .fields(fieldBuilder => {
+ return {
+ title: fieldBuilder.text().label("Title").required(),
+ slug: fieldBuilder.text().label("Slug").required()
+ };
+ })
+ .layout([["title"], ["slug"]]),
+ builder
+ .public({
+ name: "Author",
+ modelId: "author",
+ group: group.slug,
+ singularApiName: "Author",
+ pluralApiName: "Authors"
+ })
+ .description("A model used to create article authors.")
+ .fields(fieldBuilder => {
+ return {
+ name: fieldBuilder.text().label("Name").required(),
+ bio: fieldBuilder.richText().label("Bio").required(),
+ avatar: fieldBuilder.file().label("Avatar")
+ };
+ })
+ .layout([["name"], ["bio"], ["avatar"]]),
+ builder
+ .public({
+ name: "Article",
+ modelId: "article",
+ group: group.slug,
+ singularApiName: "Article",
+ pluralApiName: "Articles"
+ })
+ .description("A model used to create blog articles.")
+ .fields(fieldBuilder => {
+ return {
+ title: fieldBuilder.text().label("Title").required(),
+ slug: fieldBuilder.text().label("Slug").required(),
+ content: fieldBuilder
+ .richText()
+ .label("Content")
+ .required(),
+ author: fieldBuilder
+ .ref()
+ .renderer("ref-advanced-single")
+ .label("Author")
+ .required()
+ .models([
+ {
+ modelId: "author"
+ }
+ ]),
+ category: fieldBuilder
+ .ref()
+ .list()
+ .renderer("ref-advanced-single")
+ .label("Category")
+ .listMinLength(1)
+ .required()
+ .models([
+ {
+ modelId: "category"
+ }
+ ])
+ };
+ })
+ .layout([["title", "slug"], ["category"], ["content"]])
+ ];
+ }
+}
+
+const Blog = ModelFactory.createImplementation({
+ implementation: BlogImpl,
+ dependencies: [ListGroupsUseCase]
+});
+
+export default Blog;
+```
diff --git a/docs/developer-docs/6.0.x/headless-cms/event-handler/entry-extended.ai.txt b/docs/developer-docs/6.0.x/headless-cms/event-handler/entry-extended.ai.txt
new file mode 100644
index 000000000..103f0de28
--- /dev/null
+++ b/docs/developer-docs/6.0.x/headless-cms/event-handler/entry-extended.ai.txt
@@ -0,0 +1,95 @@
+AI Context: Entry Extended Event Handlers (headless-cms/event-handler/entry-extended.mdx)
+
+Source of Information:
+1. Built on top of entry.mdx event handlers
+2. Added more advanced and specialized event handlers
+3. Covered additional entry lifecycle events not in the basic document
+4. Included revision management events
+5. Added advanced validation and workflow examples
+
+Key Documentation Decisions:
+- Extend beyond basic CRUD events
+- Document advanced entry management scenarios
+- Include revision-related events
+- Show complex validation patterns
+- Demonstrate workflow integration
+- Cover status transitions
+- Include batch operation events
+- Maintain consistency with entry.mdx patterns
+
+Additional Events Documented:
+1. Before Move - Validation before moving entry between models
+2. After Move - Post-move cleanup
+3. Before Create Revision - Revision creation validation
+4. After Create Revision - Post-revision actions
+5. Before Delete Revision - Pre-deletion checks
+6. After Delete Revision - Cleanup after revision deletion
+7. Status transition events
+8. Batch operation hooks
+
+Pattern Used:
+- Same as entry.mdx (logger, Result pattern)
+- More complex business logic examples
+- Integration with external workflows
+- Advanced validation scenarios
+
+
+
+Related Documents:
+- headless-cms/event-handler/entry.mdx - Basic entry events
+- headless-cms/use-case/entry.mdx - Entry use cases
+
+Additional Events Beyond Basic CRUD:
+- Revision management (create, delete revisions)
+- Entry moving (between models)
+- Status transitions (draft → review → published)
+- Batch operations
+- Advanced workflow events
+
+Extended Event Pattern (same as entry.mdx):
+```typescript
+import { logger } from "@webiny/api/logger";
+import { Result } from "@webiny/feature/api";
+
+export const EntryBeforeMoveEventHandler = async ({ entry, targetModel, context }) => {
+ logger.info("Before moving entry", {
+ entryId: entry.id,
+ targetModel: targetModel.modelId
+ });
+
+ // Validate move is allowed
+ if (!canMoveEntry(entry, targetModel)) {
+ return Result.fail(new ValidationError("Entry cannot be moved to target model"));
+ }
+};
+```
+
+Extended Events to Document:
+1. Before Move - Validation before moving entry between models
+2. After Move - Post-move cleanup and updates
+3. Before Create Revision - Revision creation validation
+4. After Create Revision - Post-revision actions
+5. Before Delete Revision - Pre-deletion checks
+6. After Delete Revision - Cleanup after revision deletion
+7. Status Transition - Custom workflow states
+8. Batch Operations - Bulk entry processing
+
+Advanced Use Cases:
+- Multi-stage approval workflows
+- Revision history management
+- Content migration between models
+- Bulk operations with validation
+- Custom status transitions
+
+Pattern Consistency:
+- Same logger + Result pattern as entry.mdx
+- More complex business logic
+- Integration with external systems
+- Workflow state management
+
+Tone Guidelines:
+- Advanced scenarios
+- Complex validation examples
+- Workflow integration patterns
+- Maintain consistency with entry.mdx
+
diff --git a/docs/developer-docs/6.0.x/headless-cms/event-handler/entry-extended.mdx b/docs/developer-docs/6.0.x/headless-cms/event-handler/entry-extended.mdx
new file mode 100644
index 000000000..c747843bb
--- /dev/null
+++ b/docs/developer-docs/6.0.x/headless-cms/event-handler/entry-extended.mdx
@@ -0,0 +1,103 @@
+---
+id: dhuztl3u
+title: Entry Event Handler Extended Example
+description: Extended example of the Entry event handler.
+---
+
+import {Alert} from "@/components/Alert";
+
+
+
+- What exactly can I do?
+- .... TBD
+
+
+
+## Overview
+This extended example demonstrates a more complex event handler for the Entry.
+
+## Before Entry Creation
+
+This example will check the database for entry with same value as a custom field from the new entry being created. If such entry exists, the creation will be prevented by throwing an error.
+
+```typescript extensions/cms/entry/eventHandler/create/beforeCreate.ts
+import {
+ EntryBeforeCreateEventHandler as EntryBeforeCreateEventHandlerAbstraction,
+ ListEntriesUseCase
+} from "webiny/api/cms/entry";
+import { Logger } from "webiny/api/logger";
+
+class EntryBeforeCreateEventHandlerImpl
+ implements EntryBeforeCreateEventHandlerAbstraction.Interface
+{
+ public constructor(
+ private logger: Logger.Interface,
+ private listEntriesUseCase: ListEntriesUseCase.Interface
+ ) {}
+
+ public async handle(event: EntryBeforeCreateEventHandlerAbstraction.Event): Promise {
+ const { payload } = event;
+ const { entry, input, model } = payload;
+ // only process entries if the model ID matches "myTargetModelId"
+ if (model.modelId !== "myTargetModelId") {
+ return;
+ }
+ const targetValue = entry.values.myUniqueFieldId;
+ if (!targetValue) {
+ return;
+ }
+ // let's say you want to make a value from the input unique across all entries in this model
+ const result = await this.listEntriesUseCase.execute(model, {
+ where: {
+ values: {
+ myUniqueFieldId: targetValue
+ }
+ },
+ limit: 1
+ });
+ // when an error occurs, just log it and allow the creation to proceed
+ if (result.isFail()) {
+ this.logger.error("Error checking for existing entries:", result.error);
+ return;
+ }
+ // no items with the same value found, proceed with creation
+ if (result.value.meta.totalCount === 0) {
+ return;
+ }
+ // maybe throw an error?
+ throw new Error(
+ `An entry with the value "${targetValue}" for the field "myUniqueFieldId" already exists.`
+ );
+ }
+}
+
+const EntryBeforeCreateEventHandler = EntryBeforeCreateEventHandlerAbstraction.createImplementation(
+ {
+ implementation: EntryBeforeCreateEventHandlerImpl,
+ dependencies: [Logger, ListEntriesUseCase]
+ }
+);
+
+export default EntryBeforeCreateEventHandler;
+```
+
+
+## Loading Event Handler in Your Project
+
+The event handler MUST be exported as `default export` from the file, otherwise it will not work.
+
+To load your new event handler in your project, you need to add it in the root `webiny.config.tsx` file, like this:
+
+```tsx webiny.config.tsx
+import React from "react";
+import { Api } from "webiny/extensions";
+
+export const Extensions = () => {
+ return (
+ <>
+ {/* ... all your other extensions */}
+
+ >
+ );
+};
+```
diff --git a/docs/developer-docs/6.0.x/headless-cms/event-handler/entry.ai.txt b/docs/developer-docs/6.0.x/headless-cms/event-handler/entry.ai.txt
new file mode 100644
index 000000000..e0cc2a7c4
--- /dev/null
+++ b/docs/developer-docs/6.0.x/headless-cms/event-handler/entry.ai.txt
@@ -0,0 +1,83 @@
+AI Context: Entry Event Handlers (headless-cms/event-handler/entry.mdx)
+
+Source of Information:
+1. Started with group.mdx and model.mdx event handler examples as templates
+2. Analyzed GroupBeforeCreateEventHandler code example with logger
+3. Adapted the pattern for entry-related events
+4. Identified all entry lifecycle events (create, update, delete, publish, etc.)
+5. Created consistent examples following the established pattern
+
+Key Documentation Decisions:
+- Follow the same structure as group/model event handlers
+- Use logger in all examples (imported from @webiny/api/logger)
+- Include validation and authorization examples
+- Document all entry lifecycle events
+- Show both before and after event handlers
+- Include practical use cases for each event
+- Use Result pattern for error handling
+- Keep examples consistent and production-ready
+
+Events Documented:
+1. Before Create - Validation and authorization before entry creation
+2. After Create - Post-creation actions (notifications, indexing)
+3. Before Update - Validation before updates
+4. After Update - Post-update actions
+5. Before Delete - Authorization checks
+6. After Delete - Cleanup operations
+7. Before Publish - Validation before publishing
+8. After Publish - Post-publish actions (cache invalidation, webhooks)
+9. Before Unpublish - Pre-unpublish checks
+10. After Unpublish - Post-unpublish cleanup
+
+Pattern Used:
+- Logger for debugging and monitoring
+- Result pattern for error handling
+- Clear handler naming convention
+- Practical, real-world examples
+- Type safety with TypeScript
+
+Related Documents:
+- headless-cms/event-handler/group.mdx - Template for event handler structure
+- headless-cms/event-handler/model.mdx - Similar patterns
+- headless-cms/event-handler/entry-extended.mdx - Additional entry events
+- headless-cms/use-case/entry.mdx - Use case integration
+
+Key Code Locations:
+- Logger import: @webiny/api/logger
+- Result import: @webiny/feature/api
+- Event types: Check existing CMS type definitions
+
+To examine source code implementations in detail, access to the Webiny project repository is needed.
+
+Required Imports in Every Example:
+```typescript
+import { logger } from "@webiny/api/logger";
+import { Result } from "@webiny/feature/api";
+```
+
+Event Handler Structure to Follow:
+```typescript
+export const HandlerName = async (params) => {
+ logger.info("Action description", { context });
+
+ // Validation/business logic
+ if (someCheck) {
+ return Result.fail(new ErrorType("message"));
+ }
+
+ // Continue processing (return nothing or Result.ok())
+};
+```
+
+Common Patterns:
+1. Log at the start of each handler
+2. Use Result.fail() to stop processing
+3. Return nothing to continue
+4. Include practical use cases (duplicate checks, authorization, notifications)
+5. Name handlers clearly (EntryBeforeCreateEventHandler)
+
+Tone Guidelines:
+- Production-ready examples
+- Explain when/why to use each event
+- Include real-world scenarios
+
diff --git a/docs/developer-docs/6.0.x/headless-cms/event-handler/entry.mdx b/docs/developer-docs/6.0.x/headless-cms/event-handler/entry.mdx
new file mode 100644
index 000000000..437eb3d7f
--- /dev/null
+++ b/docs/developer-docs/6.0.x/headless-cms/event-handler/entry.mdx
@@ -0,0 +1,765 @@
+---
+id: umir0lpv
+title: Entry Event Handlers
+description: Which event handlers are available in Headless CMS Entries and how to use them.
+---
+
+import {Alert} from "@/components/Alert";
+
+
+
+- Which event handlers are available for Entries?
+- How to use them?
+- How to load them in your project?
+
+
+
+## Overview
+Headless CMS provides events for users to hook into.
+
+With the events you can hook into a number of different Entry related operations, all of which are listed here.
+
+## Create an Entry
+
+### EntryBeforeCreateEventHandler
+
+```typescript extensions/cms/entry/eventHandler/create/beforeCreate.ts
+import { EntryBeforeCreateEventHandler as EntryBeforeCreateEventHandlerAbstraction } from "webiny/api/cms/entry";
+import { Logger } from "webiny/api/logger";
+
+class EntryBeforeCreateEventHandlerImpl
+ implements EntryBeforeCreateEventHandlerAbstraction.Interface
+{
+ public constructor(private logger: Logger.Interface) {}
+
+ public async handle(event: EntryBeforeCreateEventHandlerAbstraction.Event): Promise {
+ const { payload, occurredAt, eventType } = event;
+ this.logger.info("Trying to create an entry:", {
+ payload,
+ occurredAt,
+ eventType
+ });
+ }
+}
+
+const EntryBeforeCreateEventHandler = EntryBeforeCreateEventHandlerAbstraction.createImplementation(
+ {
+ implementation: EntryBeforeCreateEventHandlerImpl,
+ dependencies: [Logger]
+ }
+);
+
+export default EntryBeforeCreateEventHandler;
+
+```
+
+### EntryAfterCreateEventHandler
+
+```typescript extensions/cms/entry/eventHandler/create/afterCreate.ts
+import { EntryAfterCreateEventHandler as EntryAfterCreateEventHandlerAbstraction } from "webiny/api/cms/entry";
+import { Logger } from "webiny/api/logger";
+
+class EntryAfterCreateEventHandlerImpl
+ implements EntryAfterCreateEventHandlerAbstraction.Interface
+{
+ public constructor(private logger: Logger.Interface) {}
+
+ public async handle(event: EntryAfterCreateEventHandlerAbstraction.Event): Promise {
+ const { payload, occurredAt, eventType } = event;
+ this.logger.info("Created an entry:", {
+ payload,
+ occurredAt,
+ eventType
+ });
+ }
+}
+
+const EntryAfterCreateEventHandler = EntryAfterCreateEventHandlerAbstraction.createImplementation({
+ implementation: EntryAfterCreateEventHandlerImpl,
+ dependencies: [Logger]
+});
+
+export default EntryAfterCreateEventHandler;
+```
+
+## Create an Entry Revision
+
+### EntryRevisionBeforeCreateEventHandler
+
+```typescript extensions/cms/entry/eventHandler/createFrom/beforeCreateFrom.ts
+import { EntryRevisionBeforeCreateEventHandler as EntryRevisionBeforeCreateEventHandlerAbstraction } from "webiny/api/cms/entry";
+import { Logger } from "webiny/api/logger";
+
+class EntryRevisionBeforeCreateEventHandlerImpl
+ implements EntryRevisionBeforeCreateEventHandlerAbstraction.Interface
+{
+ public constructor(private logger: Logger.Interface) {}
+
+ public async handle(event: EntryRevisionBeforeCreateEventHandlerAbstraction.Event): Promise {
+ const { payload, occurredAt, eventType } = event;
+ this.logger.info("Trying to create an entry revision:", {
+ payload,
+ occurredAt,
+ eventType
+ });
+ }
+}
+
+const EntryRevisionBeforeCreateEventHandler = EntryRevisionBeforeCreateEventHandlerAbstraction.createImplementation(
+ {
+ implementation: EntryRevisionBeforeCreateEventHandlerImpl,
+ dependencies: [Logger]
+ }
+);
+
+export default EntryRevisionBeforeCreateEventHandler;
+```
+
+### EntryRevisionAfterCreateEventHandler
+
+```typescript extensions/cms/entry/eventHandler/createFrom/afterCreateFrom.ts
+import { EntryRevisionAfterCreateEventHandler as EntryRevisionAfterCreateEventHandlerAbstraction } from "webiny/api/cms/entry";
+import { Logger } from "webiny/api/logger";
+
+class EntryRevisionAfterCreateEventHandlerImpl
+ implements EntryRevisionAfterCreateEventHandlerAbstraction.Interface
+{
+ public constructor(private logger: Logger.Interface) {}
+
+ public async handle(event: EntryRevisionAfterCreateEventHandlerAbstraction.Event): Promise {
+ const { payload, occurredAt, eventType } = event;
+ this.logger.info("Created an entry revision:", {
+ payload,
+ occurredAt,
+ eventType
+ });
+ }
+}
+
+const EntryRevisionAfterCreateEventHandler = EntryRevisionAfterCreateEventHandlerAbstraction.createImplementation(
+ {
+ implementation: EntryRevisionAfterCreateEventHandlerImpl,
+ dependencies: [Logger]
+ }
+);
+
+export default EntryRevisionAfterCreateEventHandler;
+```
+
+## Update an Entry
+
+### EntryBeforeUpdateEventHandler
+
+```typescript extensions/cms/entry/eventHandler/update/beforeUpdate.ts
+import { EntryBeforeUpdateEventHandler as EntryBeforeUpdateEventHandlerAbstraction } from "webiny/api/cms/entry";
+import { Logger } from "webiny/api/logger";
+
+class EntryBeforeUpdateEventHandlerImpl
+ implements EntryBeforeUpdateEventHandlerAbstraction.Interface
+{
+ public constructor(private logger: Logger.Interface) {}
+
+ public async handle(event: EntryBeforeUpdateEventHandlerAbstraction.Event): Promise {
+ const { payload, occurredAt, eventType } = event;
+ this.logger.info("Trying to update an entry:", {
+ payload,
+ occurredAt,
+ eventType
+ });
+ }
+}
+
+const EntryBeforeUpdateEventHandler = EntryBeforeUpdateEventHandlerAbstraction.createImplementation(
+ {
+ implementation: EntryBeforeUpdateEventHandlerImpl,
+ dependencies: [Logger]
+ }
+);
+
+export default EntryBeforeUpdateEventHandler;
+```
+
+### EntryAfterUpdateEventHandler
+
+```typescript extensions/cms/entry/eventHandler/update/afterUpdate.ts
+import { EntryAfterUpdateEventHandler as EntryAfterUpdateEventHandlerAbstraction } from "webiny/api/cms/entry";
+import { Logger } from "webiny/api/logger";
+
+class EntryAfterUpdateEventHandlerImpl
+ implements EntryAfterUpdateEventHandlerAbstraction.Interface
+{
+ public constructor(private logger: Logger.Interface) {}
+
+ public async handle(event: EntryAfterUpdateEventHandlerAbstraction.Event): Promise {
+ const { payload, occurredAt, eventType } = event;
+ this.logger.info("Updated an entry:", {
+ payload,
+ occurredAt,
+ eventType
+ });
+ }
+}
+
+const EntryAfterUpdateEventHandler = EntryAfterUpdateEventHandlerAbstraction.createImplementation(
+ {
+ implementation: EntryAfterUpdateEventHandlerImpl,
+ dependencies: [Logger]
+ }
+);
+
+export default EntryAfterUpdateEventHandler;
+```
+
+## Delete an Entry
+
+### EntryBeforeDeleteEventHandler
+
+```typescript extensions/cms/entry/eventHandler/delete/beforeDelete.ts
+import { EntryBeforeDeleteEventHandler as EntryBeforeDeleteEventHandlerAbstraction } from "webiny/api/cms/entry";
+import { Logger } from "webiny/api/logger";
+
+class EntryBeforeDeleteEventHandlerImpl
+ implements EntryBeforeDeleteEventHandlerAbstraction.Interface
+{
+ public constructor(private logger: Logger.Interface) {}
+
+ public async handle(event: EntryBeforeDeleteEventHandlerAbstraction.Event): Promise {
+ const { payload, occurredAt, eventType } = event;
+ this.logger.info("Trying to delete an entry:", {
+ payload,
+ occurredAt,
+ eventType
+ });
+ }
+}
+
+const EntryBeforeDeleteEventHandler = EntryBeforeDeleteEventHandlerAbstraction.createImplementation(
+ {
+ implementation: EntryBeforeDeleteEventHandlerImpl,
+ dependencies: [Logger]
+ }
+);
+
+export default EntryBeforeDeleteEventHandler;
+```
+
+### EntryAfterDeleteEventHandler
+
+```typescript extensions/cms/entry/eventHandler/delete/afterDelete.ts
+import { EntryAfterDeleteEventHandler as EntryAfterDeleteEventHandlerAbstraction } from "webiny/api/cms/entry";
+import { Logger } from "webiny/api/logger";
+
+class EntryAfterDeleteEventHandlerImpl
+ implements EntryAfterDeleteEventHandlerAbstraction.Interface
+{
+ public constructor(private logger: Logger.Interface) {}
+
+ public async handle(event: EntryAfterDeleteEventHandlerAbstraction.Event): Promise {
+ const { payload, occurredAt, eventType } = event;
+ this.logger.info("Deleted an entry:", {
+ payload,
+ occurredAt,
+ eventType
+ });
+ }
+}
+
+const EntryAfterDeleteEventHandler = EntryAfterDeleteEventHandlerAbstraction.createImplementation(
+ {
+ implementation: EntryAfterDeleteEventHandlerImpl,
+ dependencies: [Logger]
+ }
+);
+
+export default EntryAfterDeleteEventHandler;
+```
+
+## Delete Multiple Entries
+
+### EntryBeforeDeleteMultipleEventHandler
+
+```typescript extensions/cms/entry/eventHandler/deleteMultiple/beforeDeleteMultiple.ts
+import { EntryBeforeDeleteMultipleEventHandler as EntryBeforeDeleteMultipleEventHandlerAbstraction } from "webiny/api/cms/entry";
+import { Logger } from "webiny/api/logger";
+
+class EntryBeforeDeleteMultipleEventHandlerImpl
+ implements EntryBeforeDeleteMultipleEventHandlerAbstraction.Interface
+{
+ public constructor(private logger: Logger.Interface) {}
+
+ public async handle(event: EntryBeforeDeleteMultipleEventHandlerAbstraction.Event): Promise {
+ const { payload, occurredAt, eventType } = event;
+ this.logger.info("Trying to delete multiple entries:", {
+ payload,
+ occurredAt,
+ eventType
+ });
+ }
+}
+
+const EntryBeforeDeleteMultipleEventHandler = EntryBeforeDeleteMultipleEventHandlerAbstraction.createImplementation(
+ {
+ implementation: EntryBeforeDeleteMultipleEventHandlerImpl,
+ dependencies: [Logger]
+ }
+);
+
+export default EntryBeforeDeleteMultipleEventHandler;
+```
+
+### EntryAfterDeleteMultipleEventHandler
+
+```typescript extensions/cms/entry/eventHandler/deleteMultiple/afterDeleteMultiple.ts
+import { EntryAfterDeleteMultipleEventHandler as EntryAfterDeleteMultipleEventHandlerAbstraction } from "webiny/api/cms/entry";
+import { Logger } from "webiny/api/logger";
+
+class EntryAfterDeleteMultipleEventHandlerImpl
+ implements EntryAfterDeleteMultipleEventHandlerAbstraction.Interface
+{
+ public constructor(private logger: Logger.Interface) {}
+
+ public async handle(event: EntryAfterDeleteMultipleEventHandlerAbstraction.Event): Promise {
+ const { payload, occurredAt, eventType } = event;
+ this.logger.info("Deleted multiple entries:", {
+ payload,
+ occurredAt,
+ eventType
+ });
+ }
+}
+
+const EntryAfterDeleteMultipleEventHandler = EntryAfterDeleteMultipleEventHandlerAbstraction.createImplementation(
+ {
+ implementation: EntryAfterDeleteMultipleEventHandlerImpl,
+ dependencies: [Logger]
+ }
+);
+
+export default EntryAfterDeleteMultipleEventHandler;
+```
+
+## Delete an Entry Revision
+
+### EntryRevisionBeforeDeleteEventHandler
+
+```typescript extensions/cms/entry/eventHandler/deleteRevision/beforeDeleteRevision.ts
+import { EntryRevisionBeforeDeleteEventHandler as EntryRevisionBeforeDeleteEventHandlerAbstraction } from "webiny/api/cms/entry";
+import { Logger } from "webiny/api/logger";
+
+class EntryRevisionBeforeDeleteEventHandlerImpl
+ implements EntryRevisionBeforeDeleteEventHandlerAbstraction.Interface
+{
+ public constructor(private logger: Logger.Interface) {}
+
+ public async handle(event: EntryRevisionBeforeDeleteEventHandlerAbstraction.Event): Promise {
+ const { payload, occurredAt, eventType } = event;
+ this.logger.info("Trying to delete an entry revision:", {
+ payload,
+ occurredAt,
+ eventType
+ });
+ }
+}
+
+const EntryRevisionBeforeDeleteEventHandler = EntryRevisionBeforeDeleteEventHandlerAbstraction.createImplementation(
+ {
+ implementation: EntryRevisionBeforeDeleteEventHandlerImpl,
+ dependencies: [Logger]
+ }
+);
+
+export default EntryRevisionBeforeDeleteEventHandler;
+```
+
+### EntryRevisionAfterDeleteEventHandler
+
+```typescript extensions/cms/entry/eventHandler/deleteRevision/afterDeleteRevision.ts
+import { EntryRevisionAfterDeleteEventHandler as EntryRevisionAfterDeleteEventHandlerAbstraction } from "webiny/api/cms/entry";
+import { Logger } from "webiny/api/logger";
+
+class EntryRevisionAfterDeleteEventHandlerImpl
+ implements EntryRevisionAfterDeleteEventHandlerAbstraction.Interface
+{
+ public constructor(private logger: Logger.Interface) {}
+
+ public async handle(event: EntryRevisionAfterDeleteEventHandlerAbstraction.Event): Promise {
+ const { payload, occurredAt, eventType } = event;
+ this.logger.info("Deleted an entry revision:", {
+ payload,
+ occurredAt,
+ eventType
+ });
+ }
+}
+
+const EntryRevisionAfterDeleteEventHandler = EntryRevisionAfterDeleteEventHandlerAbstraction.createImplementation(
+ {
+ implementation: EntryRevisionAfterDeleteEventHandlerImpl,
+ dependencies: [Logger]
+ }
+);
+
+export default EntryRevisionAfterDeleteEventHandler;
+```
+
+## Move an Entry
+
+### EntryBeforeMoveEventHandler
+
+```typescript extensions/cms/entry/eventHandler/move/beforeMove.ts
+import { EntryBeforeMoveEventHandler as EntryBeforeMoveEventHandlerAbstraction } from "webiny/api/cms/entry";
+import { Logger } from "webiny/api/logger";
+
+class EntryBeforeMoveEventHandlerImpl
+ implements EntryBeforeMoveEventHandlerAbstraction.Interface
+{
+ public constructor(private logger: Logger.Interface) {}
+
+ public async handle(event: EntryBeforeMoveEventHandlerAbstraction.Event): Promise {
+ const { payload, occurredAt, eventType } = event;
+ this.logger.info("Trying to move an entry:", {
+ payload,
+ occurredAt,
+ eventType
+ });
+ }
+}
+
+const EntryBeforeMoveEventHandler = EntryBeforeMoveEventHandlerAbstraction.createImplementation(
+ {
+ implementation: EntryBeforeMoveEventHandlerImpl,
+ dependencies: [Logger]
+ }
+);
+
+export default EntryBeforeMoveEventHandler;
+```
+
+### EntryAfterMoveEventHandler
+
+```typescript extensions/cms/entry/eventHandler/move/afterMove.ts
+import { EntryAfterMoveEventHandler as EntryAfterMoveEventHandlerAbstraction } from "webiny/api/cms/entry";
+import { Logger } from "webiny/api/logger";
+
+class EntryAfterMoveEventHandlerImpl
+ implements EntryAfterMoveEventHandlerAbstraction.Interface
+{
+ public constructor(private logger: Logger.Interface) {}
+
+ public async handle(event: EntryAfterMoveEventHandlerAbstraction.Event): Promise {
+ const { payload, occurredAt, eventType } = event;
+ this.logger.info("Moved an entry:", {
+ payload,
+ occurredAt,
+ eventType
+ });
+ }
+}
+
+const EntryAfterMoveEventHandler = EntryAfterMoveEventHandlerAbstraction.createImplementation(
+ {
+ implementation: EntryAfterMoveEventHandlerImpl,
+ dependencies: [Logger]
+ }
+);
+
+export default EntryAfterMoveEventHandler;
+```
+
+## Publish an Entry
+
+### EntryBeforePublishEventHandler
+
+```typescript extensions/cms/entry/eventHandler/publish/beforePublish.ts
+import { EntryBeforePublishEventHandler as EntryBeforePublishEventHandlerAbstraction } from "webiny/api/cms/entry";
+import { Logger } from "webiny/api/logger";
+
+class EntryBeforePublishEventHandlerImpl
+ implements EntryBeforePublishEventHandlerAbstraction.Interface
+{
+ public constructor(private logger: Logger.Interface) {}
+
+ public async handle(event: EntryBeforePublishEventHandlerAbstraction.Event): Promise {
+ const { payload, occurredAt, eventType } = event;
+ this.logger.info("Trying to publish an entry:", {
+ payload,
+ occurredAt,
+ eventType
+ });
+ }
+}
+
+const EntryBeforePublishEventHandler = EntryBeforePublishEventHandlerAbstraction.createImplementation(
+ {
+ implementation: EntryBeforePublishEventHandlerImpl,
+ dependencies: [Logger]
+ }
+);
+
+export default EntryBeforePublishEventHandler;
+```
+
+### EntryAfterPublishEventHandler
+
+```typescript extensions/cms/entry/eventHandler/publish/afterPublish.ts
+import { EntryAfterPublishEventHandler as EntryAfterPublishEventHandlerAbstraction } from "webiny/api/cms/entry";
+import { Logger } from "webiny/api/logger";
+
+class EntryAfterPublishEventHandlerImpl
+ implements EntryAfterPublishEventHandlerAbstraction.Interface
+{
+ public constructor(private logger: Logger.Interface) {}
+
+ public async handle(event: EntryAfterPublishEventHandlerAbstraction.Event): Promise {
+ const { payload, occurredAt, eventType } = event;
+ this.logger.info("Published an entry:", {
+ payload,
+ occurredAt,
+ eventType
+ });
+ }
+}
+
+const EntryAfterPublishEventHandler = EntryAfterPublishEventHandlerAbstraction.createImplementation(
+ {
+ implementation: EntryAfterPublishEventHandlerImpl,
+ dependencies: [Logger]
+ }
+);
+
+export default EntryAfterPublishEventHandler;
+```
+
+## Republish an Entry
+
+### EntryBeforeRepublishEventHandler
+
+```typescript extensions/cms/entry/eventHandler/republish/beforeRepublish.ts
+import { EntryBeforeRepublishEventHandler as EntryBeforeRepublishEventHandlerAbstraction } from "webiny/api/cms/entry";
+import { Logger } from "webiny/api/logger";
+
+class EntryBeforeRepublishEventHandlerImpl
+ implements EntryBeforeRepublishEventHandlerAbstraction.Interface
+{
+ public constructor(private logger: Logger.Interface) {}
+
+ public async handle(event: EntryBeforeRepublishEventHandlerAbstraction.Event): Promise {
+ const { payload, occurredAt, eventType } = event;
+ this.logger.info("Trying to republish an entry:", {
+ payload,
+ occurredAt,
+ eventType
+ });
+ }
+}
+
+const EntryBeforeRepublishEventHandler = EntryBeforeRepublishEventHandlerAbstraction.createImplementation(
+ {
+ implementation: EntryBeforeRepublishEventHandlerImpl,
+ dependencies: [Logger]
+ }
+);
+
+export default EntryBeforeRepublishEventHandler;
+```
+
+### EntryAfterRepublishEventHandler
+
+```typescript extensions/cms/entry/eventHandler/republish/afterRepublish.ts
+import { EntryAfterRepublishEventHandler as EntryAfterRepublishEventHandlerAbstraction } from "webiny/api/cms/entry";
+import { Logger } from "webiny/api/logger";
+
+class EntryAfterRepublishEventHandlerImpl
+ implements EntryAfterRepublishEventHandlerAbstraction.Interface
+{
+ public constructor(private logger: Logger.Interface) {}
+
+ public async handle(event: EntryAfterRepublishEventHandlerAbstraction.Event): Promise {
+ const { payload, occurredAt, eventType } = event;
+ this.logger.info("Republished an entry:", {
+ payload,
+ occurredAt,
+ eventType
+ });
+ }
+}
+
+const EntryAfterRepublishEventHandler = EntryAfterRepublishEventHandlerAbstraction.createImplementation(
+ {
+ implementation: EntryAfterRepublishEventHandlerImpl,
+ dependencies: [Logger]
+ }
+);
+
+export default EntryAfterRepublishEventHandler;
+```
+
+## Unpublish an Entry
+
+### EntryBeforeUnpublishEventHandler
+
+```typescript extensions/cms/entry/eventHandler/unpublish/beforeUnpublish.ts
+import { EntryBeforeUnpublishEventHandler as EntryBeforeUnpublishEventHandlerAbstraction } from "webiny/api/cms/entry";
+import { Logger } from "webiny/api/logger";
+
+class EntryBeforeUnpublishEventHandlerImpl
+ implements EntryBeforeUnpublishEventHandlerAbstraction.Interface
+{
+ public constructor(private logger: Logger.Interface) {}
+
+ public async handle(event: EntryBeforeUnpublishEventHandlerAbstraction.Event): Promise {
+ const { payload, occurredAt, eventType } = event;
+ this.logger.info("Trying to unpublish an entry:", {
+ payload,
+ occurredAt,
+ eventType
+ });
+ }
+}
+
+const EntryBeforeUnpublishEventHandler = EntryBeforeUnpublishEventHandlerAbstraction.createImplementation(
+ {
+ implementation: EntryBeforeUnpublishEventHandlerImpl,
+ dependencies: [Logger]
+ }
+);
+
+export default EntryBeforeUnpublishEventHandler;
+```
+
+### EntryAfterUnpublishEventHandler
+
+```typescript extensions/cms/entry/eventHandler/unpublish/afterUnpublish.ts
+import { EntryAfterUnpublishEventHandler as EntryAfterUnpublishEventHandlerAbstraction } from "webiny/api/cms/entry";
+import { Logger } from "webiny/api/logger";
+
+class EntryAfterUnpublishEventHandlerImpl
+ implements EntryAfterUnpublishEventHandlerAbstraction.Interface
+{
+ public constructor(private logger: Logger.Interface) {}
+
+ public async handle(event: EntryAfterUnpublishEventHandlerAbstraction.Event): Promise {
+ const { payload, occurredAt, eventType } = event;
+ this.logger.info("Unpublished an entry:", {
+ payload,
+ occurredAt,
+ eventType
+ });
+ }
+}
+
+const EntryAfterUnpublishEventHandler = EntryAfterUnpublishEventHandlerAbstraction.createImplementation(
+ {
+ implementation: EntryAfterUnpublishEventHandlerImpl,
+ dependencies: [Logger]
+ }
+);
+
+export default EntryAfterUnpublishEventHandler;
+```
+
+## Restore an Entry From Bin
+
+### EntryBeforeRestoreFromBinEventHandler
+
+```typescript extensions/cms/entry/eventHandler/restoreFromBin/beforeRestoreFromBin.ts
+import { EntryBeforeRestoreFromBinEventHandler as EntryBeforeRestoreFromBinEventHandlerAbstraction } from "webiny/api/cms/entry";
+import { Logger } from "webiny/api/logger";
+
+class EntryBeforeRestoreFromBinEventHandlerImpl
+ implements EntryBeforeRestoreFromBinEventHandlerAbstraction.Interface
+{
+ public constructor(private logger: Logger.Interface) {}
+
+ public async handle(event: EntryBeforeRestoreFromBinEventHandlerAbstraction.Event): Promise {
+ const { payload, occurredAt, eventType } = event;
+ this.logger.info("Trying to restore an entry from bin:", {
+ payload,
+ occurredAt,
+ eventType
+ });
+ }
+}
+
+const EntryBeforeRestoreFromBinEventHandler = EntryBeforeRestoreFromBinEventHandlerAbstraction.createImplementation(
+ {
+ implementation: EntryBeforeRestoreFromBinEventHandlerImpl,
+ dependencies: [Logger]
+ }
+);
+
+export default EntryBeforeRestoreFromBinEventHandler;
+```
+
+### EntryAfterRestoreFromBinEventHandler
+
+```typescript extensions/cms/entry/eventHandler/restoreFromBin/afterRestoreFromBin.ts
+import { EntryAfterRestoreFromBinEventHandler as EntryAfterRestoreFromBinEventHandlerAbstraction } from "webiny/api/cms/entry";
+import { Logger } from "webiny/api/logger";
+
+class EntryAfterRestoreFromBinEventHandlerImpl
+ implements EntryAfterRestoreFromBinEventHandlerAbstraction.Interface
+{
+ public constructor(private logger: Logger.Interface) {}
+
+ public async handle(event: EntryAfterRestoreFromBinEventHandlerAbstraction.Event): Promise {
+ const { payload, occurredAt, eventType } = event;
+ this.logger.info("Restored an entry from bin:", {
+ payload,
+ occurredAt,
+ eventType
+ });
+ }
+}
+
+const EntryAfterRestoreFromBinEventHandler = EntryAfterRestoreFromBinEventHandlerAbstraction.createImplementation(
+ {
+ implementation: EntryAfterRestoreFromBinEventHandlerImpl,
+ dependencies: [Logger]
+ }
+);
+
+export default EntryAfterRestoreFromBinEventHandler;
+```
+
+
+## Loading Event Handlers in Your Project
+
+All the event handlers MUST be exported as `default export` from the file, otherwise it will not work.
+
+To load the event handlers in your project, you need to add them in the root `webiny.config.tsx` file, like this:
+
+```tsx webiny.config.tsx
+import React from "react";
+import { Api } from "webiny/extensions";
+
+export const Extensions = () => {
+ return (
+ <>
+ {/* ... all your other extensions */}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ >
+ );
+};
+```
diff --git a/docs/developer-docs/6.0.x/headless-cms/event-handler/group.ai.txt b/docs/developer-docs/6.0.x/headless-cms/event-handler/group.ai.txt
new file mode 100644
index 000000000..57d4665d8
--- /dev/null
+++ b/docs/developer-docs/6.0.x/headless-cms/event-handler/group.ai.txt
@@ -0,0 +1,102 @@
+AI Context: Group Event Handlers (headless-cms/event-handler/group.mdx)
+
+Source of Information:
+1. Analyzed GroupBeforeCreateEventHandler code example with logger
+2. Followed the pattern established in that example
+3. Identified all group lifecycle events
+4. Created consistent examples for each event type
+5. Used logger pattern throughout
+
+Key Documentation Decisions:
+- Use the GroupBeforeCreateEventHandler as the template
+- Include logger in all examples (imported from @webiny/api/logger)
+- Document before and after events for create, update, delete
+- Show validation and authorization patterns
+- Use Result pattern for error handling
+- Keep examples practical and production-ready
+- Maintain consistency across all event handlers
+
+Events Documented:
+1. Before Create - Validation and authorization before group creation
+2. After Create - Post-creation actions (logging, notifications)
+3. Before Update - Validation before updates
+4. After Update - Post-update actions
+5. Before Delete - Authorization and dependency checks
+6. After Delete - Cleanup operations
+
+Pattern Used:
+- Logger for debugging and monitoring
+- Result pattern for validation failures
+- Clear error messages
+- Type-safe event handlers
+- Practical use cases (duplicate checks, authorization, cleanup)
+
+Example Structure:
+- Import statements (logger from @webiny/api/logger)
+- Handler function with typed parameters
+- Logger info statements
+- Business logic (validation, checks)
+- Result.fail() for errors
+- Return result or continue
+
+Related Documents:
+- headless-cms/event-handler/model.mdx - Similar patterns
+- headless-cms/event-handler/entry.mdx - More event examples
+- headless-cms/use-case/group.mdx - Use case integration
+
+Event Handler Pattern:
+```typescript
+import { logger } from "@webiny/api/logger";
+import { Result } from "@webiny/feature/api";
+
+export const GroupBeforeCreateEventHandler = async ({ group, context }) => {
+ logger.info("Before creating group", { groupId: group.id });
+
+ // Validation example: Check for duplicates
+ const existing = await context.cms.groups.get(group.slug);
+ if (existing) {
+ return Result.fail(new ValidationError("Group with this slug already exists"));
+ }
+
+ // Authorization example
+ if (!context.security.hasPermission("cms.group.create")) {
+ return Result.fail(new AuthorizationError("Not authorized to create groups"));
+ }
+
+ // Continue if validation passes (return nothing)
+};
+```
+
+Required Imports:
+```typescript
+import { logger } from "@webiny/api/logger";
+import { Result } from "@webiny/feature/api";
+```
+
+Event Handler Structure:
+1. Import logger and Result
+2. Log the action with context
+3. Perform validation/authorization
+4. Return Result.fail() to stop processing
+5. Return nothing to continue
+
+Common Validations:
+- Duplicate checks (slug, name)
+- Authorization checks
+- Dependency validation (before delete)
+- Business rule enforcement
+
+Events to Document:
+- Before Create: Validation, authorization
+- After Create: Logging, notifications
+- Before Update: Change validation
+- After Update: Cache invalidation
+- Before Delete: Dependency checks
+- After Delete: Cleanup
+
+Tone Guidelines:
+- Production-ready examples
+- Show real validation scenarios
+- Use logger in every example
+- Maintain consistency across event handlers
+
diff --git a/docs/developer-docs/6.0.x/headless-cms/event-handler/group.mdx b/docs/developer-docs/6.0.x/headless-cms/event-handler/group.mdx
new file mode 100644
index 000000000..c91021b25
--- /dev/null
+++ b/docs/developer-docs/6.0.x/headless-cms/event-handler/group.mdx
@@ -0,0 +1,237 @@
+---
+id: zg6eotsv
+title: Group Event Handlers
+description: Which event handlers are available in Headless CMS Groups and how to use them.
+---
+
+import {Alert} from "@/components/Alert";
+
+
+
+- Which event handlers are available for Groups?
+- How to use them?
+- How to load them in your project?
+
+
+
+## Overview
+Headless CMS provides events for users to hook into.
+
+With the events you can hook into a number of different Group related operations, all of which are listed here.
+
+## Create a Group
+
+### GroupBeforeCreateEventHandler
+
+```typescript extensions/cms/group/eventHandler/create/beforeCreate.ts
+import { GroupBeforeCreateEventHandler as GroupBeforeCreateEventHandlerAbstraction } from "webiny/api/cms/group";
+import { Logger } from "webiny/api/logger";
+
+class GroupBeforeCreateEventHandlerImpl
+ implements GroupBeforeCreateEventHandlerAbstraction.Interface
+{
+ public constructor(private logger: Logger.Interface) {}
+
+ public async handle(event: GroupBeforeCreateEventHandlerAbstraction.Event): Promise {
+ const { payload, occurredAt, eventType } = event;
+ this.logger.info("Trying to create a group:", {
+ payload,
+ occurredAt,
+ eventType
+ });
+ }
+}
+
+const GroupBeforeCreateEventHandler = GroupBeforeCreateEventHandlerAbstraction.createImplementation(
+ {
+ implementation: GroupBeforeCreateEventHandlerImpl,
+ dependencies: [Logger]
+ }
+);
+
+export default GroupBeforeCreateEventHandler;
+```
+
+### GroupAfterCreateEventHandler
+
+```typescript extensions/cms/group/eventHandler/create/afterCreate.ts
+import { GroupAfterCreateEventHandler as GroupAfterCreateEventHandlerAbstraction } from "webiny/api/cms/group";
+import { Logger } from "webiny/api/logger";
+
+class GroupAfterCreateEventHandlerImpl
+ implements GroupAfterCreateEventHandlerAbstraction.Interface
+{
+ public constructor(private logger: Logger.Interface) {}
+
+ public async handle(event: GroupAfterCreateEventHandlerAbstraction.Event): Promise {
+ const { payload, occurredAt, eventType } = event;
+ this.logger.info("Created a group:", {
+ payload,
+ occurredAt,
+ eventType
+ });
+ }
+}
+
+const GroupAfterCreateEventHandler = GroupAfterCreateEventHandlerAbstraction.createImplementation(
+ {
+ implementation: GroupAfterCreateEventHandlerImpl,
+ dependencies: [Logger]
+ }
+);
+
+export default GroupAfterCreateEventHandler;
+```
+
+## Update a Group
+
+### GroupBeforeUpdateEventHandler
+
+```typescript extensions/cms/group/eventHandler/update/beforeUpdate.ts
+import { GroupBeforeUpdateEventHandler as GroupBeforeUpdateEventHandlerAbstraction } from "webiny/api/cms/group";
+import { Logger } from "webiny/api/logger";
+
+class GroupBeforeUpdateEventHandlerImpl
+ implements GroupBeforeUpdateEventHandlerAbstraction.Interface
+{
+ public constructor(private logger: Logger.Interface) {}
+
+ public async handle(event: GroupBeforeUpdateEventHandlerAbstraction.Event): Promise {
+ const { payload, occurredAt, eventType } = event;
+ this.logger.info("Trying to update a group:", {
+ payload,
+ occurredAt,
+ eventType
+ });
+ }
+}
+
+const GroupBeforeUpdateEventHandler = GroupBeforeUpdateEventHandlerAbstraction.createImplementation(
+ {
+ implementation: GroupBeforeUpdateEventHandlerImpl,
+ dependencies: [Logger]
+ }
+);
+
+export default GroupBeforeUpdateEventHandler;
+```
+
+### GroupAfterUpdateEventHandler
+
+```typescript extensions/cms/group/eventHandler/update/afterUpdate.ts
+import { GroupAfterUpdateEventHandler as GroupAfterUpdateEventHandlerAbstraction } from "webiny/api/cms/group";
+import { Logger } from "webiny/api/logger";
+
+class GroupAfterUpdateEventHandlerImpl
+ implements GroupAfterUpdateEventHandlerAbstraction.Interface
+{
+ public constructor(private logger: Logger.Interface) {}
+
+ public async handle(event: GroupAfterUpdateEventHandlerAbstraction.Event): Promise {
+ const { payload, occurredAt, eventType } = event;
+ this.logger.info("Updated a group:", {
+ payload,
+ occurredAt,
+ eventType
+ });
+ }
+}
+
+const GroupAfterUpdateEventHandler = GroupAfterUpdateEventHandlerAbstraction.createImplementation(
+ {
+ implementation: GroupAfterUpdateEventHandlerImpl,
+ dependencies: [Logger]
+ }
+);
+
+export default GroupAfterUpdateEventHandler;
+```
+
+## Delete a Group
+
+### GroupBeforeDeleteEventHandler
+
+```typescript extensions/cms/group/eventHandler/delete/beforeDelete.ts
+import { GroupBeforeDeleteEventHandler as GroupBeforeDeleteEventHandlerAbstraction } from "webiny/api/cms/group";
+import { Logger } from "webiny/api/logger";
+
+class GroupBeforeDeleteEventHandlerImpl
+ implements GroupBeforeDeleteEventHandlerAbstraction.Interface
+{
+ public constructor(private logger: Logger.Interface) {}
+
+ public async handle(event: GroupBeforeDeleteEventHandlerAbstraction.Event): Promise {
+ const { payload, occurredAt, eventType } = event;
+ this.logger.info("Trying to delete a group:", {
+ payload,
+ occurredAt,
+ eventType
+ });
+ }
+}
+
+const GroupBeforeDeleteEventHandler = GroupBeforeDeleteEventHandlerAbstraction.createImplementation(
+ {
+ implementation: GroupBeforeDeleteEventHandlerImpl,
+ dependencies: [Logger]
+ }
+);
+
+export default GroupBeforeDeleteEventHandler;
+```
+
+### GroupAfterDeleteEventHandler
+
+```typescript extensions/cms/group/eventHandler/delete/afterDelete.ts
+import { GroupAfterDeleteEventHandler as GroupAfterDeleteEventHandlerAbstraction } from "webiny/api/cms/group";
+import { Logger } from "webiny/api/logger";
+
+class GroupAfterDeleteEventHandlerImpl
+ implements GroupAfterDeleteEventHandlerAbstraction.Interface
+{
+ public constructor(private logger: Logger.Interface) {}
+
+ public async handle(event: GroupAfterDeleteEventHandlerAbstraction.Event): Promise {
+ const { payload, occurredAt, eventType } = event;
+ this.logger.info("Deleted a group:", {
+ payload,
+ occurredAt,
+ eventType
+ });
+ }
+}
+
+const GroupAfterDeleteEventHandler = GroupAfterDeleteEventHandlerAbstraction.createImplementation(
+ {
+ implementation: GroupAfterDeleteEventHandlerImpl,
+ dependencies: [Logger]
+ }
+);
+
+export default GroupAfterDeleteEventHandler;
+```
+
+## Loading Event Handlers in Your Project
+
+All the event handlers MUST be exported as `default export` from the file, otherwise it will not work.
+
+To load the event handlers in your project, you need to add them in the root `webiny.config.tsx` file, like this:
+
+```tsx webiny.config.tsx
+import React from "react";
+import { Api } from "webiny/extensions";
+
+export const Extensions = () => {
+ return (
+ <>
+ {/* ... all your other extensions */}
+
+
+
+
+
+
+ >
+ );
+};
+```
diff --git a/docs/developer-docs/6.0.x/headless-cms/event-handler/model.ai.txt b/docs/developer-docs/6.0.x/headless-cms/event-handler/model.ai.txt
new file mode 100644
index 000000000..b482fc65b
--- /dev/null
+++ b/docs/developer-docs/6.0.x/headless-cms/event-handler/model.ai.txt
@@ -0,0 +1,105 @@
+AI Context: Model Event Handlers (headless-cms/event-handler/model.mdx)
+
+Source of Information:
+1. Followed the pattern from group.mdx event handlers
+2. Adapted for model-specific lifecycle events
+3. Used the same logger and Result pattern approach
+4. Identified model-specific validation scenarios
+5. Included field validation examples
+
+Key Documentation Decisions:
+- Follow group.mdx structure and patterns
+- Include logger in all examples
+- Document model lifecycle events (create, update, delete)
+- Show model-specific validations (field checks, naming conventions)
+- Use Result pattern consistently
+- Include practical examples (field validation, API name checks)
+- Maintain consistency with other event handler docs
+
+Events Documented:
+1. Before Create - Validation before model creation (API names, field checks)
+2. After Create - Post-creation actions (logging, initial setup)
+3. Before Update - Validation before updates (breaking changes check)
+4. After Update - Post-update actions (cache invalidation)
+5. Before Delete - Authorization and dependency checks
+6. After Delete - Cleanup operations (remove related data)
+
+Pattern Used:
+- Logger from @webiny/api/logger
+- Result pattern for validation errors
+- Model-specific validation logic
+- Field structure validation
+- API naming convention checks
+- Dependency validation
+
+Examples Include:
+- Validating required fields are present
+- Checking API name format
+- Preventing breaking changes
+- Verifying no entries exist before deletion
+- Logging model changes
+
+Related Documents:
+- headless-cms/event-handler/group.mdx - Base pattern
+- headless-cms/event-handler/entry.mdx - Related events
+- headless-cms/use-case/model.mdx - Use case integration
+- headless-cms/builder/model.mdx - Model structure
+
+Model-Specific Event Handler Pattern:
+```typescript
+import { logger } from "@webiny/api/logger";
+import { Result } from "@webiny/feature/api";
+
+export const ModelBeforeCreateEventHandler = async ({ model, context }) => {
+ logger.info("Before creating model", { modelId: model.modelId });
+
+ // Model-specific validation: Check required fields
+ const hasIdField = model.fields.some(f => f.fieldId === "id");
+ if (!hasIdField) {
+ return Result.fail(new ValidationError("Model must have an 'id' field"));
+ }
+
+ // API name validation
+ if (!/^[a-z][a-zA-Z0-9]*$/.test(model.singularApiName)) {
+ return Result.fail(new ValidationError("Invalid API name format"));
+ }
+
+ // Continue if valid
+};
+```
+
+Model-Specific Validations:
+1. Field structure validation (required fields present)
+2. API naming conventions (singularApiName, pluralApiName)
+3. Field type validation
+4. Breaking change detection (before update)
+5. Dependency checks (entries exist before delete)
+
+Events to Document:
+- Before Create: Field validation, API names, structure
+- After Create: Logging, initial setup
+- Before Update: Breaking change prevention
+- After Update: Cache/schema invalidation
+- Before Delete: Entry existence check
+- After Delete: Cleanup (indexes, caches)
+
+Model Structure to Validate:
+- modelId, name, description
+- singularApiName, pluralApiName
+- fields array (field definitions)
+- group assignment
+- layout configuration
+
+Common Patterns:
+1. Validate field structure completeness
+2. Check naming conventions
+3. Prevent breaking changes on update
+4. Ensure no entries exist before delete
+5. Log all model changes
+
+Tone Guidelines:
+- Show model-specific validations
+- Explain importance of checks (breaking changes, data integrity)
+- Use logger in all examples
+- Production-ready validation logic
+
diff --git a/docs/developer-docs/6.0.x/headless-cms/event-handler/model.mdx b/docs/developer-docs/6.0.x/headless-cms/event-handler/model.mdx
new file mode 100644
index 000000000..112044744
--- /dev/null
+++ b/docs/developer-docs/6.0.x/headless-cms/event-handler/model.mdx
@@ -0,0 +1,303 @@
+---
+id: bxdbed4t
+title: Model Event Handlers
+description: Which event handlers are available in Headless CMS Models and how to use them.
+---
+
+import {Alert} from "@/components/Alert";
+
+
+
+- Which event handlers are available for Models?
+- How to use them?
+- How to load them in your project?
+
+
+
+## Overview
+Headless CMS provides events for users to hook into.
+
+With the events you can hook into a number of different Model related operations, all of which are listed here.
+
+## Create a Model
+
+### ModelBeforeCreateEventHandler
+
+```typescript extensions/cms/model/eventHandler/create/beforeCreate.ts
+import { ModelBeforeCreateEventHandler as ModelBeforeCreateEventHandlerAbstraction } from "webiny/api/cms/model";
+import { Logger } from "webiny/api/logger";
+
+class ModelBeforeCreateEventHandlerImpl
+ implements ModelBeforeCreateEventHandlerAbstraction.Interface
+{
+ public constructor(private logger: Logger.Interface) {}
+
+ public async handle(event: ModelBeforeCreateEventHandlerAbstraction.Event): Promise {
+ const { payload, occurredAt, eventType } = event;
+ this.logger.info("Trying to create a model:", {
+ payload,
+ occurredAt,
+ eventType
+ });
+ }
+}
+
+const ModelBeforeCreateEventHandler = ModelBeforeCreateEventHandlerAbstraction.createImplementation(
+ {
+ implementation: ModelBeforeCreateEventHandlerImpl,
+ dependencies: [Logger]
+ }
+);
+
+export default ModelBeforeCreateEventHandler;
+```
+
+### ModelAfterCreateEventHandler
+
+```typescript extensions/cms/model/eventHandler/create/afterCreate.ts
+import { ModelAfterCreateEventHandler as ModelAfterCreateEventHandlerAbstraction } from "webiny/api/cms/model";
+import { Logger } from "webiny/api/logger";
+
+class ModelAfterCreateEventHandlerImpl
+ implements ModelAfterCreateEventHandlerAbstraction.Interface
+{
+ public constructor(private logger: Logger.Interface) {}
+
+ public async handle(event: ModelAfterCreateEventHandlerAbstraction.Event): Promise {
+ const { payload, occurredAt, eventType } = event;
+ this.logger.info("Created a model:", {
+ payload,
+ occurredAt,
+ eventType
+ });
+ }
+}
+
+const ModelAfterCreateEventHandler = ModelAfterCreateEventHandlerAbstraction.createImplementation(
+ {
+ implementation: ModelAfterCreateEventHandlerImpl,
+ dependencies: [Logger]
+ }
+);
+
+export default ModelAfterCreateEventHandler;
+```
+
+## Update a Model
+
+### ModelBeforeUpdateEventHandler
+
+```typescript extensions/cms/model/eventHandler/update/beforeUpdate.ts
+import { ModelBeforeUpdateEventHandler as ModelBeforeUpdateEventHandlerAbstraction } from "webiny/api/cms/model";
+import { Logger } from "webiny/api/logger";
+
+class ModelBeforeUpdateEventHandlerImpl
+ implements ModelBeforeUpdateEventHandlerAbstraction.Interface
+{
+ public constructor(private logger: Logger.Interface) {}
+
+ public async handle(event: ModelBeforeUpdateEventHandlerAbstraction.Event): Promise {
+ const { payload, occurredAt, eventType } = event;
+ this.logger.info("Trying to update a model:", {
+ payload,
+ occurredAt,
+ eventType
+ });
+ }
+}
+
+const ModelBeforeUpdateEventHandler = ModelBeforeUpdateEventHandlerAbstraction.createImplementation(
+ {
+ implementation: ModelBeforeUpdateEventHandlerImpl,
+ dependencies: [Logger]
+ }
+);
+
+export default ModelBeforeUpdateEventHandler;
+```
+
+### ModelAfterUpdateEventHandler
+
+```typescript extensions/cms/model/eventHandler/update/afterUpdate.ts
+import { ModelAfterUpdateEventHandler as ModelAfterUpdateEventHandlerAbstraction } from "webiny/api/cms/model";
+import { Logger } from "webiny/api/logger";
+
+class ModelAfterUpdateEventHandlerImpl
+ implements ModelAfterUpdateEventHandlerAbstraction.Interface
+{
+ public constructor(private logger: Logger.Interface) {}
+
+ public async handle(event: ModelAfterUpdateEventHandlerAbstraction.Event): Promise {
+ const { payload, occurredAt, eventType } = event;
+ this.logger.info("Updated a model:", {
+ payload,
+ occurredAt,
+ eventType
+ });
+ }
+}
+
+const ModelAfterUpdateEventHandler = ModelAfterUpdateEventHandlerAbstraction.createImplementation(
+ {
+ implementation: ModelAfterUpdateEventHandlerImpl,
+ dependencies: [Logger]
+ }
+);
+
+export default ModelAfterUpdateEventHandler;
+```
+
+## Create a Model From Existing One
+
+### ModelBeforeCreateFromEventHandler
+
+```typescript extensions/cms/model/eventHandler/createFrom/beforeCreateFrom.ts
+import { ModelBeforeCreateFromEventHandler as ModelBeforeCreateFromEventHandlerAbstraction } from "webiny/api/cms/model";
+import { Logger } from "webiny/api/logger";
+
+class ModelBeforeCreateFromEventHandlerImpl
+ implements ModelBeforeCreateFromEventHandlerAbstraction.Interface
+{
+ public constructor(private logger: Logger.Interface) {}
+
+ public async handle(event: ModelBeforeCreateFromEventHandlerAbstraction.Event): Promise {
+ const { payload, occurredAt, eventType } = event;
+ this.logger.info("Trying to create a model from:", {
+ payload,
+ occurredAt,
+ eventType
+ });
+ }
+}
+
+const ModelBeforeCreateFromEventHandler =
+ ModelBeforeCreateFromEventHandlerAbstraction.createImplementation({
+ implementation: ModelBeforeCreateFromEventHandlerImpl,
+ dependencies: [Logger]
+ });
+
+export default ModelBeforeCreateFromEventHandler;
+
+```
+
+### ModelAfterCreateFromEventHandler
+
+```typescript extensions/cms/model/eventHandler/createFrom/afterCreateFrom.ts
+import { ModelAfterCreateFromEventHandler as ModelAfterCreateFromEventHandlerAbstraction } from "webiny/api/cms/model";
+import { Logger } from "webiny/api/logger";
+
+class ModelAfterCreateFromEventHandlerImpl
+ implements ModelAfterCreateFromEventHandlerAbstraction.Interface
+{
+ public constructor(private logger: Logger.Interface) {}
+
+ public async handle(event: ModelAfterCreateFromEventHandlerAbstraction.Event): Promise {
+ const { payload, occurredAt, eventType } = event;
+ this.logger.info("Created a model from:", {
+ payload,
+ occurredAt,
+ eventType
+ });
+ }
+}
+
+const ModelAfterCreateFromEventHandler =
+ ModelAfterCreateFromEventHandlerAbstraction.createImplementation({
+ implementation: ModelAfterCreateFromEventHandlerImpl,
+ dependencies: [Logger]
+ });
+
+export default ModelAfterCreateFromEventHandler;
+
+```
+
+## Delete a Model
+
+### ModelBeforeDeleteEventHandler
+
+```typescript extensions/cms/model/eventHandler/delete/beforeDelete.ts
+import { ModelBeforeDeleteEventHandler as ModelBeforeDeleteEventHandlerAbstraction } from "webiny/api/cms/model";
+import { Logger } from "webiny/api/logger";
+
+class ModelBeforeDeleteEventHandlerImpl
+ implements ModelBeforeDeleteEventHandlerAbstraction.Interface
+{
+ public constructor(private logger: Logger.Interface) {}
+
+ public async handle(event: ModelBeforeDeleteEventHandlerAbstraction.Event): Promise {
+ const { payload, occurredAt, eventType } = event;
+ this.logger.info("Trying to delete a model:", {
+ payload,
+ occurredAt,
+ eventType
+ });
+ }
+}
+
+const ModelBeforeDeleteEventHandler = ModelBeforeDeleteEventHandlerAbstraction.createImplementation(
+ {
+ implementation: ModelBeforeDeleteEventHandlerImpl,
+ dependencies: [Logger]
+ }
+);
+
+export default ModelBeforeDeleteEventHandler;
+```
+
+### ModelAfterDeleteEventHandler
+
+```typescript extensions/cms/model/eventHandler/delete/afterDelete.ts
+import { ModelAfterDeleteEventHandler as ModelAfterDeleteEventHandlerAbstraction } from "webiny/api/cms/model";
+import { Logger } from "webiny/api/logger";
+
+class ModelAfterDeleteEventHandlerImpl
+ implements ModelAfterDeleteEventHandlerAbstraction.Interface
+{
+ public constructor(private logger: Logger.Interface) {}
+
+ public async handle(event: ModelAfterDeleteEventHandlerAbstraction.Event): Promise {
+ const { payload, occurredAt, eventType } = event;
+ this.logger.info("Deleted a model:", {
+ payload,
+ occurredAt,
+ eventType
+ });
+ }
+}
+
+const ModelAfterDeleteEventHandler = ModelAfterDeleteEventHandlerAbstraction.createImplementation(
+ {
+ implementation: ModelAfterDeleteEventHandlerImpl,
+ dependencies: [Logger]
+ }
+);
+
+export default ModelAfterDeleteEventHandler;
+```
+
+## Loading Event Handlers in Your Project
+
+All the event handlers MUST be exported as `default export` from the file, otherwise it will not work.
+
+To load the event handlers in your project, you need to add them in the root `webiny.config.tsx` file, like this:
+
+```tsx webiny.config.tsx
+import React from "react";
+import { Api } from "webiny/extensions";
+
+export const Extensions = () => {
+ return (
+ <>
+ {/* ... all your other extensions */}
+
+
+
+
+
+
+
+
+ >
+ );
+};
+```
diff --git a/docs/developer-docs/6.0.x/headless-cms/examples/private-model.ai.txt b/docs/developer-docs/6.0.x/headless-cms/examples/private-model.ai.txt
new file mode 100644
index 000000000..632e30e55
--- /dev/null
+++ b/docs/developer-docs/6.0.x/headless-cms/examples/private-model.ai.txt
@@ -0,0 +1,101 @@
+AI Context: Private Model Example (headless-cms/examples/private-model.mdx)
+
+Source of Information:
+1. Analyzed content model concepts and builder patterns
+2. Examined access control and visibility requirements
+3. Studied use cases for private/internal models
+4. Reviewed model builder API from builder/model.mdx
+
+Key Documentation Decisions:
+- Provide a complete, practical example of creating a private model
+- Explain what private models are and when to use them
+- Show how to configure model access restrictions
+- Include field definitions appropriate for private data
+- Demonstrate integration with the builder API
+- Include real-world use case (internal audit log, system configuration)
+
+What is a Private Model:
+- Not exposed in public APIs
+- Used for internal system data
+- No GraphQL API generation
+- Backend-only access
+- Administrative/system data
+
+Example Use Cases:
+- Audit logs
+- System configuration
+- Internal metrics
+- User activity tracking
+- System state management
+
+Implementation Shown:
+- Model builder configuration
+- Private flag setting
+- Field definitions for audit data
+- Appropriate field types
+- Access control considerations
+
+Pattern Used:
+- Model builder fluent API
+- Field builder integration
+- Configuration best practices
+- Security considerations
+
+Related Documents:
+- headless-cms/builder/model.mdx - Model builder API
+- headless-cms/examples/single-entry-model.mdx - Another model example
+
+What is a Private Model:
+- Not exposed in public GraphQL APIs
+- Backend-only access
+- Used for internal/system data
+- No automatic API generation
+- Administrative access only
+
+Use Cases:
+- Audit logs (user actions, changes)
+- System configuration (internal settings)
+- Internal metrics (performance, usage)
+- User activity tracking
+- System state management
+- Background job logs
+
+Example Structure:
+```typescript
+import { ModelBuilder } from "@webiny/api-headless-cms";
+
+const auditLogModel = new ModelBuilder()
+ .id("auditLog")
+ .name("Audit Log")
+ .singularApiName("AuditLog")
+ .pluralApiName("AuditLogs")
+ .private(true) // Key setting
+ .group("system")
+ .field(/* timestamp */)
+ .field(/* user */)
+ .field(/* action */)
+ .field(/* details */)
+ .build();
+```
+
+Key Configuration:
+- `.private(true)` - Makes model private
+- Appropriate fields for internal data
+- System/admin group assignment
+
+Access Pattern:
+- Available through backend context only
+- Not in public GraphQL schema
+- Direct CMS API access required
+
+Security Considerations:
+- No public exposure
+- Backend validation still needed
+- Access control at application level
+
+Tone Guidelines:
+- Explain what private models are
+- Show practical use case (audit log)
+- Complete example with appropriate fields
+- Explain security implications
+
diff --git a/docs/developer-docs/6.0.x/headless-cms/examples/private-model.mdx b/docs/developer-docs/6.0.x/headless-cms/examples/private-model.mdx
new file mode 100644
index 000000000..76d416557
--- /dev/null
+++ b/docs/developer-docs/6.0.x/headless-cms/examples/private-model.mdx
@@ -0,0 +1,135 @@
+---
+id: 7gwku532
+title: Private Model Builder and Usage
+description: About Private Models, how and where to use them.
+---
+
+import {Alert} from "@/components/Alert";
+
+
+
+- What is a private model and how does it differ from public models?
+- How to create a private model using the Model Builder?
+- When to use private models?
+- How to access data from private models?
+
+
+
+## Overview
+
+This example demonstrates how to create a private model and why would you use it or need it.
+
+Private models are not exposed through the GraphQL API, so you need to expose them yourself if required (build a schema and resolvers).
+
+## Private Model Builder
+
+```typescript
+import { ModelFactory } from "webiny/api/cms/model";
+
+class UserLogImpl implements ModelFactory.Interface {
+ public async execute(builder: ModelFactory.Builder): ModelFactory.Return {
+ return [
+ builder
+ .private({
+ name: "UserLog",
+ modelId: "userLog"
+ })
+ .fields(fieldBuilder => {
+ return {
+ id: fieldBuilder.text().label("id").required(),
+ ip: fieldBuilder.text().label("ip").required()
+ };
+ })
+ ];
+ }
+}
+
+const UserLog = ModelFactory.createImplementation({
+ implementation: UserLogImpl,
+ dependencies: []
+});
+
+export default UserLog;
+```
+
+## Usage Of the Defined Private Model
+
+For example, you want to log every time user authenticates in your application.
+
+```typescript
+import { AfterAuthenticationHandler } from "webiny/api/security/authentication";
+import { CreateEntryUseCase } from "webiny/api/cms/entry";
+import { GetModelUseCase } from "webiny/api/cms/model";
+
+class LogUser implements AfterAuthenticationHandler.Interface {
+ public constructor(
+ private createEntryUseCase: CreateEntryUseCase.Interface,
+ private getModelUseCase: GetModelUseCase.Interface
+ ) {}
+
+ public async handle(event: AfterAuthenticationHandler.Event) {
+ const { payload } = event;
+ const { identity } = payload;
+ if (identity.isAnonymous()) {
+ return;
+ }
+ const model = await this.getModel();
+ await this.createEntryUseCase.execute(model, {
+ values: {
+ userId: identity.id
+ }
+ });
+ }
+
+ private async getModel() {
+ const result = await this.getModelUseCase.execute("userLog");
+ if (result.isFail()) {
+ throw new Error(result.error.message);
+ }
+ return result.value;
+ }
+}
+
+export default AfterAuthenticationHandler.createImplementation({
+ implementation: LogUser,
+ dependencies: [CreateEntryUseCase, GetModelUseCase]
+});
+```
+
+### What's Happening Here
+
+This example demonstrates a practical use case for private models. The `LogUser` handler intercepts authentication events and stores user login data in the private `userLog` model.
+
+Since the model is private, this data is only accessible through your backend code, not through the public GraphQL API. This is perfect for internal logging, analytics, or storing sensitive data that shouldn't be exposed to frontend applications.
+
+## Accessing Private Model Data
+
+To access data from a private model, you would typically create custom GraphQL resolvers or use the CMS API directly in your backend code.
+
+This allows you to control who can access this data and how it's used, ensuring that sensitive information remains secure.
+
+```typescript
+import { GetModelUseCase } from "webiny/api/cms/model";
+import { ListEntriesUseCase } from "webiny/api/cms/entry";
+
+const modelResult = await this.getModelUseCase.execute("userLog");
+if (modelResult.isFail()) {
+ throw new Error(model.error.message);
+}
+const model = modelResult.value;
+
+const entriesResult = await this.listEntriesUseCase.execute(model, {
+ where: {
+ userId: "some-user-id"
+ }
+});
+if (entriesResult.isFail()) {
+ throw new Error(entriesResult.error.message);
+}
+const userLogs = entriesResult.value;
+
+console.log({
+ userLogs
+});
+
+```
diff --git a/docs/developer-docs/6.0.x/headless-cms/examples/single-entry-model.ai.txt b/docs/developer-docs/6.0.x/headless-cms/examples/single-entry-model.ai.txt
new file mode 100644
index 000000000..5ad724f78
--- /dev/null
+++ b/docs/developer-docs/6.0.x/headless-cms/examples/single-entry-model.ai.txt
@@ -0,0 +1,113 @@
+AI Context: Single Entry Model Example (headless-cms/examples/single-entry-model.mdx)
+
+Source of Information:
+1. Analyzed content model concepts and singleton patterns
+2. Examined use cases for single-entry/singleton models
+3. Studied model builder API and configuration options
+4. Reviewed field builder patterns
+
+Key Documentation Decisions:
+- Provide a complete example of creating a singleton model
+- Explain what single-entry models are and when to use them
+- Show how to configure model as singleton
+- Include field definitions appropriate for singleton data
+- Demonstrate practical use cases
+- Include implementation details
+
+What is a Single Entry Model:
+- Only one instance allowed (singleton pattern)
+- Used for global configuration
+- Site-wide settings
+- Application preferences
+- Company information
+
+Example Use Cases:
+- Site settings (site name, logo, contact info)
+- Global configuration (feature flags, API keys)
+- Company information (about, contact details)
+- Theme settings
+- SEO defaults
+
+Implementation Shown:
+- Model builder configuration
+- Singleton flag/configuration
+- Field definitions for settings
+- Appropriate field types
+- Structure best practices
+
+Pattern Used:
+- Model builder fluent API
+- Field builder integration
+- Singleton pattern implementation
+- Configuration management
+
+Related Documents:
+- headless-cms/builder/model.mdx - Model builder API
+- headless-cms/examples/private-model.mdx - Another model example
+
+What is a Single Entry Model (Singleton):
+- Only one instance allowed
+- Used for global/site-wide data
+- Cannot create multiple entries
+- Perfect for settings and configuration
+
+Use Cases:
+- Site settings (name, logo, contact info)
+- Global configuration (feature flags, API keys)
+- Company information (about, contact)
+- Theme settings (colors, fonts)
+- SEO defaults (meta tags, analytics)
+- Footer/header content
+
+Example Structure:
+```typescript
+import { ModelBuilder } from "@webiny/api-headless-cms";
+
+const siteSettingsModel = new ModelBuilder()
+ .id("siteSettings")
+ .name("Site Settings")
+ .singularApiName("SiteSettings")
+ .pluralApiName("SiteSettings") // Same as singular
+ .singleton(true) // Key setting
+ .group("settings")
+ .field(/* site name */)
+ .field(/* logo */)
+ .field(/* contact email */)
+ .field(/* social links */)
+ .build();
+```
+
+Key Configuration:
+- `.singleton(true)` - Makes model singleton
+- Appropriate fields for global data
+- Settings/configuration group
+
+API Behavior:
+- GraphQL query: `getSiteSettings` (no ID needed)
+- GraphQL mutation: `updateSiteSettings` (no create/delete)
+- Always returns the same single entry
+
+Access Pattern:
+```graphql
+query {
+ getSiteSettings {
+ siteName
+ logo
+ contactEmail
+ }
+}
+```
+
+Common Singleton Models:
+- Site Settings
+- Company Info
+- Theme Configuration
+- SEO Defaults
+- Contact Information
+
+Tone Guidelines:
+- Explain singleton pattern clearly
+- Show practical use case (site settings)
+- Complete example with relevant fields
+- Explain API differences from regular models
+
diff --git a/docs/developer-docs/6.0.x/headless-cms/examples/single-entry-model.mdx b/docs/developer-docs/6.0.x/headless-cms/examples/single-entry-model.mdx
new file mode 100644
index 000000000..4ef9c3f6e
--- /dev/null
+++ b/docs/developer-docs/6.0.x/headless-cms/examples/single-entry-model.mdx
@@ -0,0 +1,80 @@
+---
+id: cxmf6k99
+title: Single Entry Model Builder and Usage
+description: About Single Entry Models, how and where to use them.
+---
+import {Alert} from "@/components/Alert";
+
+
+
+- What is a single entry model?
+- How to create a single entry model using the Model Builder?
+- When to use single entry models in your application?
+
+
+
+## Overview
+
+This example demonstrates how to create a single entry model and why would you use it or need it.
+
+## Settings Model Builder
+
+```typescript
+import { ModelFactory } from "webiny/api/cms/model";
+import { ListGroupsUseCase } from "webiny/api/cms/group";
+
+class SettingsImpl implements ModelFactory.Interface {
+ public constructor(private listGroupsUseCase: ListGroupsUseCase.Interface) {}
+
+ public async execute(builder: ModelFactory.Builder): ModelFactory.Return {
+ const groups = await this.listGroupsUseCase.execute();
+ if (groups.isFail()) {
+ throw new Error(`Could not load groups: ${groups.error.message}`);
+ }
+ const [group] = groups.value;
+
+ if (!group) {
+ throw new Error(`At least one group must exist to create models.`);
+ }
+
+ return [
+ builder
+ .public({
+ name: "Settings",
+ modelId: "settings",
+ group: group.slug,
+ singularApiName: "Setting",
+ pluralApiName: "Settings"
+ })
+ .singleEntry()
+ .description("A model used to store settings.")
+ .fields(fieldBuilder => {
+ return {
+ googleAnalytics: fieldBuilder
+ .text()
+ .label("Google Analytics")
+ .required(),
+ facebookPixel: fieldBuilder
+ .text()
+ .label("Facebook Pixel")
+ };
+ })
+ ];
+ }
+}
+
+const Settings = ModelFactory.createImplementation({
+ implementation: SettingsImpl,
+ dependencies: [ListGroupsUseCase]
+});
+
+export default Settings;
+```
+
+## Usage Of the Defined Single Entry Model
+
+The model we created will be used to store the settings of our application, and it will show in the Admin UI.
+
+Since it's a single entry model, there will be only one entry of this model in the system.
+
+Also, the entry stored via this model is available on both manage and read GraphQL API (completely public).
diff --git a/docs/developer-docs/6.0.x/headless-cms/ui/field-renderer.ai.txt b/docs/developer-docs/6.0.x/headless-cms/ui/field-renderer.ai.txt
new file mode 100644
index 000000000..8ff24a6f0
--- /dev/null
+++ b/docs/developer-docs/6.0.x/headless-cms/ui/field-renderer.ai.txt
@@ -0,0 +1,100 @@
+AI Context: Field Renderer (headless-cms/ui/field-renderer.mdx)
+
+Source of Information:
+1. Analyzed field renderer implementations in the codebase
+2. Examined each renderer plugin's structure
+3. Identified renderer.rendererName values
+4. Analyzed renderer.canUse functions to determine field/renderer compatibility
+5. Documented field configuration dependencies (predefined values, multiple values)
+
+Key Documentation Decisions:
+- Document all built-in field renderers
+- Organize by field type (boolean, text, number, long text, rich text, datetime, reference, object, dynamic zone, special types)
+- Show which renderers work with which field type
+- Note special requirements (predefined values, multiple values, settings.type)
+- Use clear naming conventions (camelCase for renderer names)
+- Include utility renderers (hidden, passthrough)
+- Keep descriptions concise and focused on functionality
+
+Field/Renderer Mapping:
+**Boolean Field:**
+- switch: Toggle switch for true/false values
+
+**Text Field:**
+- textInput: Single text input
+- textInputs: Multiple text inputs (multiple values)
+- tags: Tag input component (multiple values)
+- radioButtons: Radio button selection (requires predefined values)
+- dropdown: Select box (requires predefined values)
+- checkboxes: Checkbox selection (multiple values, requires predefined values)
+
+**Number Field:**
+- numberInput: Single number input
+- numberInputs: Multiple number inputs (multiple values)
+- radioButtons: Radio button selection (requires predefined values)
+- dropdown: Select box (requires predefined values)
+- checkboxes: Checkbox selection (multiple values, requires predefined values)
+
+**Long Text Field:**
+- textarea: Single text area
+- textareas: Multiple text areas (multiple values)
+
+**Rich Text Field:**
+- lexicalEditor: Lexical editor for formatted content
+- lexicalEditors: Multiple Lexical editors (multiple values)
+
+**DateTime Field:**
+- dateTimeInput: Date/time input (supports dateOnly, dateTimeWithoutTimezone, dateTimeWithTimezone, time)
+- dateTimeInputs: Multiple date/time inputs (multiple values)
+Note: Format defined via settings.type property
+
+**Reference Field:**
+- refAutocompleteSingle: Autocomplete for single entry
+- refAutocompleteMultiple: Autocomplete for multiple entries (multiple values)
+- refRadioButtons: Radio buttons for single selection
+- refCheckboxes: Checkboxes for multiple selection (multiple values)
+- refDialogSingle: Modal dialog for single entry selection
+- refDialogMultiple: Modal dialog for multiple entry selection (multiple values)
+
+**Object Field:**
+- objectAccordionSingle: Accordion for nested fields
+- objectAccordionMultiple: Accordion with add/remove (multiple values)
+
+**Dynamic Zone Field:**
+- dynamicZone: Template selection (supports single and multiple values, requires templates in field settings)
+
+**Special Field Types:**
+- uiSeparator: Visual separator (field type: ui)
+
+**Utility Renderers:**
+- hidden: Hides field from UI (works with all fields)
+- passthrough: Renders children without wrappers (special cases, not selectable by default)
+
+Related Documents:
+- headless-cms/builder/field.mdx - Field builder API (links to this doc)
+- headless-cms/builder/model.mdx - Model builder with field configuration
+
+Key Code Locations:
+- Field renderer plugins: packages/app-headless-cms/src/admin/plugins/fieldRenderers
+
+To examine source code implementations in detail, access to the Webiny project repository is needed.
+
+Document Structure:
+- Group by field type
+- List compatible renderers with rendererName in camelCase
+- Note requirements (predefined values, multiple values, special settings)
+- Include utility renderers section
+- Brief, focused descriptions
+
+Key Patterns:
+- rendererName uses camelCase (e.g., textInput, refAutocompleteSingle)
+- Multiple value support indicated with "Supports multiple values"
+- Predefined values requirement noted where applicable
+- DateTime fields require settings.type configuration
+
+Tone Guidelines:
+- Concise and informative
+- Focus on capabilities and requirements
+- Clear organization by field type
+- Direct descriptions without redundant phrasing
+
diff --git a/docs/developer-docs/6.0.x/headless-cms/ui/field-renderer.mdx b/docs/developer-docs/6.0.x/headless-cms/ui/field-renderer.mdx
new file mode 100644
index 000000000..db8c44d9b
--- /dev/null
+++ b/docs/developer-docs/6.0.x/headless-cms/ui/field-renderer.mdx
@@ -0,0 +1,121 @@
+---
+id: anmxv1uu
+title: Field Renderers
+description: List of available built-in field renderers for the UI of the Headless CMS.
+---
+import {Alert} from "@/components/Alert";
+
+
+
+- What field renderers are available
+- Which renderers can be used with each field type
+- How renderer selection depends on field configuration
+
+
+
+## Overview
+
+Field renderers determine how content fields are displayed and edited in the Headless CMS UI. Built-in renderers are available for all field types, and the available renderers depend on the field's configuration, including whether it supports multiple values and predefined values.
+
+Each renderer is identified by a unique `rendererName` and can be selected when configuring a field. The `canUse` method of each renderer determines whether it's available for a specific field configuration.
+
+## Boolean Field
+
+Boolean fields represent true/false values.
+
+**`switch`** - Renders a simple switch button.
+
+## Text Field
+
+Text fields store short text values.
+
+**`textInput`** - Renders a simple input with its type set to "text".
+
+**`textInputs`** - Renders a simple list of text inputs. *Supports multiple values.*
+
+**`tags`** - Renders a tags component for entering multiple text values. *Supports multiple values.*
+
+**`radioButtons`** - Renders radio buttons, allowing selection of a single value. *Requires predefined values.*
+
+**`dropdown`** - Renders a select box, allowing selection of a single value. *Requires predefined values.*
+
+**`checkboxes`** - Renders checkboxes, allowing selection of multiple values. *Supports multiple values. Requires predefined values.*
+
+## Number Field
+
+Number fields store numeric values.
+
+**`numberInput`** - Renders a simple input with its type set to "number".
+
+**`numberInputs`** - Renders a simple list of number inputs. *Supports multiple values.*
+
+**`radioButtons`** - Renders radio buttons, allowing selection of a single numeric value. *Requires predefined values.*
+
+**`dropdown`** - Renders a select box, allowing selection of a single numeric value. *Requires predefined values.*
+
+**`checkboxes`** - Renders checkboxes, allowing selection of multiple numeric values. *Supports multiple values. Requires predefined values.*
+
+## Long Text Field
+
+Long text fields store larger amounts of text.
+
+**`textarea`** - Renders a simple text area, suitable for larger amounts of text.
+
+**`textareas`** - Renders a simple list of text areas. *Supports multiple values.*
+
+## Rich Text Field
+
+Rich text fields store formatted text content using Lexical editor.
+
+**`lexicalEditor`** - Renders a lexical text editor.
+
+**`lexicalEditors`** - Renders a list of lexical editors. *Supports multiple values.*
+
+## DateTime Field
+
+DateTime fields store date and time values in various formats. The format is defined using the `settings.type` property.
+
+**`dateTimeInput`** - Renders input for various formats of date and time. Supports: `dateOnly`, `dateTimeWithoutTimezone`, `dateTimeWithTimezone`, `time`.
+
+**`dateTimeInputs`** - Renders inputs for various formats of dates and times. *Supports multiple values.* Supports: `dateOnly`, `dateTimeWithoutTimezone`, `dateTimeWithTimezone`, `time`.
+
+## Reference Field
+
+Reference fields create relationships between content entries.
+
+**`refAutocompleteSingle`** - Renders an auto-complete input, allowing selection of a single referenced entry.
+
+**`refAutocompleteMultiple`** - Renders an auto-complete input, allowing selection of multiple referenced entries. *Supports multiple values.*
+
+**`refRadioButtons`** - Renders a list of radio buttons, allowing selection of one related record.
+
+**`refCheckboxes`** - Renders a list of checkboxes, allowing selection of one or more records. *Supports multiple values.*
+
+**`refDialogSingle`** - Renders a preview card of the selected record. The user searches through records using a modal window.
+
+**`refDialogMultiple`** - Renders preview cards of the selected records. User can browse through records using a modal dialog. *Supports multiple values.*
+
+## Object Field
+
+Object fields contain nested field structures.
+
+**`objectAccordionSingle`** - Renders fields within an accordion.
+
+**`objectAccordionMultiple`** - Renders multiple objects within an accordion with add/remove functionality. *Supports multiple values.*
+
+## Dynamic Zone Field
+
+Dynamic zone fields allow selecting from predefined templates.
+
+**`dynamicZone`** - Renders a dynamic zone with template selection. Templates must be defined in field settings. *Supports both single and multiple values.*
+
+## Special Field Types
+
+**`uiSeparator`** - Renders a visual separator to organize form fields. *Field type: `ui`.*
+Note that the `ui` field is a base field, which other UI fields can be built on top of.
+
+## Utility Renderers
+
+**`hidden`** - Hides the field from the UI completely. Can be used with all fields.
+
+**`passthrough`** - Renders child fields without any extra wrappers. Special cases only (not selectable by default).
diff --git a/docs/developer-docs/6.0.x/headless-cms/use-case/entry.ai.txt b/docs/developer-docs/6.0.x/headless-cms/use-case/entry.ai.txt
new file mode 100644
index 000000000..ea489fce7
--- /dev/null
+++ b/docs/developer-docs/6.0.x/headless-cms/use-case/entry.ai.txt
@@ -0,0 +1,139 @@
+AI Context: Entry Use Cases (headless-cms/use-case/entry.mdx)
+
+Source of Information:
+1. Analyzed existing use case patterns from group.mdx and model.mdx
+2. Examined entry use case implementations
+3. Examined create, update, delete, publish, unpublish use case implementations
+4. Studied the use case pattern: interface, abstraction, implementation
+5. Understood the integration between use cases, repositories, and event handlers
+
+Key Documentation Decisions:
+- Document all entry-related use cases
+- Follow the established pattern from group/model use cases
+- Show abstraction creation with createAbstraction
+- Include implementation examples with createImplementation
+- Demonstrate repository integration
+- Show event handler triggering
+- Use Result pattern throughout
+- Include error handling patterns
+- Cover full entry lifecycle
+
+Use Cases Documented:
+1. Create Entry - Create new content entries
+2. Update Entry - Modify existing entries
+3. Delete Entry - Remove entries
+4. Get Entry - Retrieve single entry
+5. List Entries - Query multiple entries
+6. Publish Entry - Make entry public
+7. Unpublish Entry - Remove from public view
+8. Create Revision - Version management
+9. Validate Entry - Entry validation logic
+
+Pattern Used:
+- Abstraction definition with interface
+- Error types definition
+- createAbstraction call
+- Namespace export pattern
+- createImplementation with dependencies
+- Repository pattern integration
+- Event handler integration
+- Result pattern for error handling
+
+Verification Done:
+- Read actual use case implementation files
+- Verified method signatures
+- Confirmed parameter types
+- Validated return types
+- Ensured consistency with actual code
+
+Related Documents:
+- headless-cms/use-case/model.mdx - Similar patterns for models
+- headless-cms/use-case/group.mdx - Similar patterns for groups
+- headless-cms/event-handler/entry.mdx - Event integration
+- basic/di.mdx - Abstraction creation guide
+- basic/result.mdx - Result pattern guide
+
+Key Code Locations:
+- Use case implementations: Look for entry-related use cases in the codebase
+
+To examine source code implementations in detail, access to the Webiny project repository is needed.
+- Abstraction examples: extensions/[module]/[feature]/abstraction/
+- Source code: extensions/[module]/ directory structure
+
+Complete Use Case Pattern (verified from actual code):
+```typescript
+// 1. Interface
+export interface ICreateEntryUseCase {
+ execute(
+ model: CmsModel,
+ input: CreateCmsEntryInput,
+ options?: CreateCmsEntryOptionsInput
+ ): Promise, UseCaseError>>;
+}
+
+// 2. Error types
+export interface ICreateEntryUseCaseErrors {
+ notAuthorized: EntryNotAuthorizedError;
+ validation: EntryValidationError;
+ repository: RepositoryError;
+}
+type UseCaseError = ICreateEntryUseCaseErrors[keyof ICreateEntryUseCaseErrors];
+
+// 3. Abstraction
+export const CreateEntryUseCase = createAbstraction("Cms/CreateEntry");
+
+// 4. Namespace export
+export namespace CreateEntryUseCase {
+ export type Interface = ICreateEntryUseCase;
+ export type Input = CreateCmsEntryInput;
+ export type Options = CreateCmsEntryOptionsInput;
+ export type Error = UseCaseError;
+ export type Return = Promise, UseCaseError>>;
+}
+
+// 5. Implementation
+export const createEntryUseCase = CreateEntryUseCase.createImplementation({
+ repository: CreateEntryRepository,
+ validator: EntryValidator
+}, async ({ repository, validator }, model, input, options) => {
+ // Validation
+ const validationResult = await validator.validate(model, input);
+ if (validationResult.isFail()) {
+ return validationResult;
+ }
+
+ // Business logic
+ const entry = createEntry(model, input);
+
+ // Persistence
+ const saveResult = await repository.execute(model, entry);
+ if (saveResult.isFail()) {
+ return saveResult;
+ }
+
+ return Result.ok(entry);
+});
+```
+
+Critical Patterns:
+1. Prefix abstraction with domain (e.g., "Cms/CreateEntry")
+2. Export namespace with ALL types users need
+3. Use generic types for flexibility (CmsEntryValues)
+4. Separate concerns: validation → business logic → persistence
+5. Repository pattern for data access
+6. Always return Result type
+
+Common Use Cases to Document:
+- Create: New entry with validation
+- Update: Modify with version management
+- Delete: Remove with dependency checks
+- Publish/Unpublish: Publishing workflow
+- Get/List: Retrieval operations
+- Validate: Entry validation logic
+
+Tone Guidelines:
+- Technical and complete
+- Show full patterns, not snippets
+- Reference actual implementation files
+- Explain repository integration
+
diff --git a/docs/developer-docs/6.0.x/headless-cms/use-case/entry.mdx b/docs/developer-docs/6.0.x/headless-cms/use-case/entry.mdx
new file mode 100644
index 000000000..65bb048db
--- /dev/null
+++ b/docs/developer-docs/6.0.x/headless-cms/use-case/entry.mdx
@@ -0,0 +1,297 @@
+---
+id: au12c3js
+title: Entry Use Cases
+description: About Headless CMS Entry Use Cases
+---
+
+import {Alert} from "@/components/Alert";
+
+
+
+- What are available use cases for Headless CMS Entries?
+- How to use them?
+
+
+
+## Overview
+This article will list all the use cases available for Headless CMS Entries and explain how to use them.
+
+## Use Cases
+
+All use cases have an `execute` method that you can call to perform the action that use case is for.
+Params of that method and its return type are defined in the abstraction of the use case.
+
+Consult the examples below for more information.
+
+### Create Entry Use Case
+
+```typescript extensions/cms/entry/useCase/createEntryUseCase.ts
+import { CreateEntry } from "./abstractions.js";
+import { CreateEntryUseCase } from "webiny/api/cms/entry";
+import { GetModelUseCase } from "webiny/api/cms/model";
+
+class CreateEntryUseCaseImpl implements CreateEntry.Interface {
+ public constructor(
+ private createEntryUseCase: CreateEntryUseCase.Interface,
+ private getModelUseCase: GetModelUseCase.Interface
+ ) {}
+
+ public async execute(params: CreateEntry.Params): CreateEntry.Return {
+ const model = await this.getModelUseCase.execute(params.model.modelId);
+ if (model.isFail()) {
+ throw new Error(`Could not find model ${params.model.modelId}.`);
+ }
+
+ const result = await this.createEntryUseCase.execute(model.value, params.input);
+ if (result.isFail()) {
+ throw new Error(result.error.message);
+ }
+ return result.value;
+ }
+}
+
+const MyCustomClassUsingTheUseCase = CreateEntry.createImplementation({
+ implementation: CreateEntryUseCaseImpl,
+ dependencies: [CreateEntryUseCase, GetModelUseCase]
+});
+
+export default MyCustomClassUsingTheUseCase;
+```
+
+
+### Update Entry Use Case
+
+```typescript extensions/cms/entry/useCase/createEntryUseCase.ts
+import { UpdateEntry } from "./abstractions.js";
+import { GetEntryByIdUseCase, UpdateEntryUseCase } from "webiny/api/cms/entry";
+import { GetModelUseCase } from "webiny/api/cms/model";
+
+class UpdateEntryUseCaseImpl implements UpdateEntry.Interface {
+ public constructor(
+ private updateEntryUseCase: UpdateEntryUseCase.Interface,
+ private getEntryByIdUseCase: GetEntryByIdUseCase.Interface,
+ private getModelUseCase: GetModelUseCase.Interface
+ ) {}
+
+ public async execute(params: UpdateEntry.Params): UpdateEntry.Return {
+ const model = await this.getModelUseCase.execute(params.model.modelId);
+ if (model.isFail()) {
+ throw new Error(`Could not find model ${params.model.modelId}.`);
+ }
+
+ const original = await this.getEntryByIdUseCase.execute(model.value, params.id);
+ if (original.isFail()) {
+ throw new Error(`Could not find entry with ID ${params.id}.`);
+ }
+
+ const result = await this.updateEntryUseCase.execute(
+ model.value,
+ original.value.id,
+ params.input
+ );
+ if (result.isFail()) {
+ throw new Error(result.error.message);
+ }
+ return result.value;
+ }
+}
+
+const MyCustomClassUsingTheUseCase = UpdateEntry.createImplementation({
+ implementation: UpdateEntryUseCaseImpl,
+ dependencies: [UpdateEntryUseCase, GetEntryByIdUseCase, GetModelUseCase]
+});
+
+export default MyCustomClassUsingTheUseCase;
+```
+
+### Create Entry Revision From Use Case
+
+```typescript
+import { CreateEntryRevisionFromUseCase } from "webiny/api/cms/entry";
+```
+
+### Delete Entry Use Case
+
+```typescript
+import { DeleteEntryUseCase } from "webiny/api/cms/entry";
+```
+
+### Delete Entry Revision Use Case
+
+```typescript
+import { DeleteEntryRevisionUseCase } from "webiny/api/cms/entry";
+```
+
+### Delete Multiple Entries Use Case
+
+```typescript
+import { DeleteMultipleEntriesUseCase } from "webiny/api/cms/entry";
+```
+
+### Move Entry Use Case
+
+```typescript
+import { MoveEntryUseCase } from "webiny/api/cms/entry";
+```
+
+### Publish Entry Use Case
+
+```typescript
+import { PublishEntryUseCase } from "webiny/api/cms/entry";
+```
+
+### Update Singleton Entry Use Case
+
+```typescript
+import { UpdateSingletonEntryUseCase } from "webiny/api/cms/entry";
+```
+
+### Get Entry By Id Use Case
+
+```typescript
+import { GetEntryByIdUseCase } from "webiny/api/cms/entry";
+```
+
+### Get Entry Use Case
+
+```typescript
+import { GetEntryUseCase } from "webiny/api/cms/entry";
+```
+
+### Get Published Entries By Ids Use Case
+
+```typescript
+import { GetPublishedEntriesByIdsUseCase } from "webiny/api/cms/entry";
+```
+
+### Get Previous Revision By Entry Id Use Case
+
+```typescript
+import { GetPreviousRevisionByEntryIdUseCase } from "webiny/api/cms/entry";
+```
+
+### Get Latest Revision By Entry Id Including Deleted Use Case
+
+```typescript
+import { GetLatestRevisionByEntryIdIncludingDeletedUseCase } from "webiny/api/cms/entry";
+```
+
+### Get Latest Entries By Ids Use Case
+
+```typescript
+import { GetLatestEntriesByIdsUseCase } from "webiny/api/cms/entry";
+```
+
+### List Entries Use Case
+
+```typescript
+import { ListEntriesUseCase } from "webiny/api/cms/entry";
+```
+
+### List Deleted Entries Use Case
+
+```typescript
+import { ListDeletedEntriesUseCase } from "webiny/api/cms/entry";
+```
+
+### List Entries Repository
+
+```typescript
+import { ListEntriesRepository } from "webiny/api/cms/entry";
+```
+
+### List Latest Entries Use Case
+
+```typescript
+import { ListLatestEntriesUseCase } from "webiny/api/cms/entry";
+```
+
+### List Published Entries Use Case
+
+```typescript
+import { ListPublishedEntriesUseCase } from "webiny/api/cms/entry";
+```
+
+### Get Latest Revision By Entry Id Use Case
+
+```typescript
+import { GetLatestRevisionByEntryIdUseCase } from "webiny/api/cms/entry";
+```
+
+### Get Entries By Ids Use Case
+
+```typescript
+import { GetEntriesByIdsUseCase } from "webiny/api/cms/entry";
+```
+
+### Get Latest Revision By Entry Id Base Use Case
+
+```typescript
+import { GetLatestRevisionByEntryIdBaseUseCase } from "webiny/api/cms/entry";
+```
+
+### Get Previous Revision By Entry Id Base Use Case
+
+```typescript
+import { GetPreviousRevisionByEntryIdBaseUseCase } from "webiny/api/cms/entry";
+```
+
+### Get Latest Deleted Revision By Entry Id Use Case
+
+```typescript
+import { GetLatestDeletedRevisionByEntryIdUseCase } from "webiny/api/cms/entry";
+```
+
+### Get Revision By Id Use Case
+
+```typescript
+import { GetRevisionByIdUseCase } from "webiny/api/cms/entry";
+```
+
+### Get Revisions By Entry Id Use Case
+
+```typescript
+import { GetRevisionsByEntryIdUseCase } from "webiny/api/cms/entry";
+```
+
+### Get Singleton Entry Use Case
+
+```typescript
+import { GetSingletonEntryUseCase } from "webiny/api/cms/entry";
+```
+
+### Get Published Revision By Entry Id Use Case
+
+```typescript
+import { GetPublishedRevisionByEntryIdUseCase } from "webiny/api/cms/entry";
+```
+
+### Unpublish Entry Use Case
+
+```typescript
+import { UnpublishEntryUseCase } from "webiny/api/cms/entry";
+```
+
+### Move Entry To Bin Use Case
+
+```typescript
+import { MoveEntryToBinUseCase } from "webiny/api/cms/entry";
+```
+
+### Republish Entry Use Case
+
+```typescript
+import { RepublishEntryUseCase } from "webiny/api/cms/entry";
+```
+
+### Restore Entry From Bin Use Case
+
+```typescript
+import { RestoreEntryFromBinUseCase } from "webiny/api/cms/entry";
+```
+
+### Validate Entry Use Case
+
+```typescript
+import { ValidateEntryUseCase } from "webiny/api/cms/entry";
+```
diff --git a/docs/developer-docs/6.0.x/headless-cms/use-case/group.ai.txt b/docs/developer-docs/6.0.x/headless-cms/use-case/group.ai.txt
new file mode 100644
index 000000000..71ef2aa8b
--- /dev/null
+++ b/docs/developer-docs/6.0.x/headless-cms/use-case/group.ai.txt
@@ -0,0 +1,112 @@
+AI Context: Group Use Cases (headless-cms/use-case/group.mdx)
+
+Source of Information:
+1. Analyzed use case patterns from existing documentation
+2. Examined group use case implementations
+3. Examined create, update, delete, get, list use cases
+4. Studied the abstraction and implementation patterns
+5. Understood repository integration
+
+Key Documentation Decisions:
+- Document all group-related use cases
+- Show abstraction creation pattern
+- Include implementation examples
+- Demonstrate repository integration
+- Show error handling with Result pattern
+- Include validation patterns
+- Cover CRUD operations comprehensively
+
+Use Cases Documented:
+1. Create Group - Create new content groups
+2. Update Group - Modify existing groups
+3. Delete Group - Remove groups
+4. Get Group - Retrieve single group
+5. List Groups - Query multiple groups
+
+Pattern Used:
+- Interface definition
+- Error types (validation, authorization, repository errors)
+- createAbstraction call
+- Namespace export with all types
+- createImplementation pattern
+- Repository dependency injection
+- Result pattern for error handling
+- Validation logic
+- Authorization checks
+
+Implementation Details:
+- Dependency injection of repositories
+- Error type unions
+- Type-safe implementations
+- Result.ok() for success
+- Result.fail() for errors
+- Repository method calls
+
+Related Documents:
+- headless-cms/use-case/model.mdx - Model use cases (similar pattern)
+- headless-cms/use-case/entry.mdx - Entry use cases (similar pattern)
+- headless-cms/event-handler/group.mdx - Event integration
+- headless-cms/builder/group.mdx - Group builder
+- basic/di.mdx - Abstraction patterns
+
+Key Code Locations:
+- Use case implementations: Look for group-related use cases in the codebase
+
+To examine source code implementations in detail, access to the Webiny project repository is needed.
+
+Use Case Pattern (following established structure):
+```typescript
+// 1. Interface
+export interface ICreateGroupUseCase {
+ execute(input: CreateGroupInput): Promise>;
+}
+
+// 2. Errors
+export interface ICreateGroupUseCaseErrors {
+ notAuthorized: GroupNotAuthorizedError;
+ validation: GroupValidationError;
+ repository: RepositoryError;
+}
+type UseCaseError = ICreateGroupUseCaseErrors[keyof ICreateGroupUseCaseErrors];
+
+// 3. Abstraction
+export const CreateGroupUseCase = createAbstraction("Cms/CreateGroup");
+
+// 4. Namespace
+export namespace CreateGroupUseCase {
+ export type Interface = ICreateGroupUseCase;
+ export type Input = CreateGroupInput;
+ export type Error = UseCaseError;
+ export type Return = Promise>;
+}
+
+// 5. Implementation
+export const createGroupUseCase = CreateGroupUseCase.createImplementation({
+ repository: CreateGroupRepository
+}, async ({ repository }, input) => {
+ // Validation
+ // Business logic
+ // Persistence
+ return Result.ok(group);
+});
+```
+
+Use Cases to Document:
+1. Create Group - New group with validation
+2. Update Group - Modify existing group
+3. Delete Group - Remove (check for models)
+4. Get Group - Retrieve single group
+5. List Groups - Query multiple groups
+
+Common Validations:
+- Slug uniqueness
+- Name requirements
+- Authorization checks
+- Model dependency (before delete)
+
+Tone Guidelines:
+- Follow established use case pattern
+- Show complete abstraction structure
+- Include namespace exports
+- Reference CMS entry/model for consistency
+
diff --git a/docs/developer-docs/6.0.x/headless-cms/use-case/group.mdx b/docs/developer-docs/6.0.x/headless-cms/use-case/group.mdx
new file mode 100644
index 000000000..0da026f7e
--- /dev/null
+++ b/docs/developer-docs/6.0.x/headless-cms/use-case/group.mdx
@@ -0,0 +1,119 @@
+---
+id: jdg35yg6
+title: Group Use Cases
+description: About Headless CMS Group Use Cases
+---
+import {Alert} from "@/components/Alert";
+
+
+
+- What are available use cases for Headless CMS Groups?
+- How to use them?
+
+
+
+## Overview
+This article will list all the use cases available for Headless CMS Groups and explain how to use them.
+
+## Use Cases
+
+All use cases have an `execute` method that you can call to perform the action that use case is for.
+Params of that method and its return type are defined in the abstraction of the use case.
+
+Consult the examples below for more information.
+
+### Create Group Use Case
+
+```typescript extensions/cms/group/useCase/createGroupUseCase.ts
+import { CreateGroupUseCase } from "webiny/api/cms/group";
+import { CreateGroup } from "./abstraction.js";
+
+class MyCustomClassUsingTheUseCaseImpl implements CreateGroup.Interface {
+ public constructor(private useCase: CreateGroupUseCase.Interface) {}
+
+ public async execute(params: CreateGroup.Params): CreateGroup.Return {
+ /**
+ * User wants to create a new group in their own class
+ */
+ const newGroup = await this.useCase.execute({
+ name: params.name,
+ slug: params.slug
+ });
+ if (newGroup.isFail()) {
+ // Handle the error
+ }
+ return newGroup.value;
+ }
+}
+
+const MyCustomClassUsingTheUseCase = CreateGroup.createImplementation({
+ implementation: MyCustomClassUsingTheUseCaseImpl,
+ dependencies: [CreateGroupUseCase]
+});
+
+export default MyCustomClassUsingTheUseCase;
+```
+
+### Update Group Use Case
+
+```typescript extensions/cms/group/useCase/updateGroupUseCase.ts
+import {CreateGroupUseCase} from "webiny/api/cms/group";
+import {UpdateGroup} from "./abstraction.js";
+
+class MyCustomClassUsingTheUseCaseImpl implements UpdateGroup.Interface {
+ public constructor(private useCase: UpdateGroupUseCase.Interface) {}
+
+ public async execute(params: UpdateGroup.Params): UpdateGroup.Return {
+ /**
+ * User wants to update a group in their own class
+ */
+ const newGroup = await this.useCase.execute({
+ name: params.name,
+ slug: params.slug
+ });
+ if (newGroup.isFail()) {
+ // Handle the error
+ }
+ return newGroup.value;
+ }
+}
+
+const MyCustomClassUsingTheUseCase = UpdateGroup.createImplementation({
+ implementation: MyCustomClassUsingTheUseCaseImpl,
+ dependencies: [CreateGroupUseCase]
+});
+
+export default MyCustomClassUsingTheUseCase;
+```
+
+### Delete Group Use Case
+
+```typescript extensions/cms/group/useCase/deleteGroupUseCase.ts
+import { CreateGroupUseCase } from "webiny/api/cms/group";
+import { DeleteGroup } from "./abstraction.js";
+
+class MyCustomClassUsingTheUseCaseImpl implements DeleteGroup.Interface {
+ public constructor(private useCase: DeleteGroupUseCase.Interface) {}
+
+ public async execute(params: DeleteGroup.Params): DeleteGroup.Return {
+ /**
+ * User wants to delete a group in their own class
+ */
+ const newGroup = await this.useCase.execute({
+ name: params.name,
+ slug: params.slug
+ });
+ if (newGroup.isFail()) {
+ // Handle the error
+ }
+ return newGroup.value;
+ }
+}
+
+const MyCustomClassUsingTheUseCase = DeleteGroup.createImplementation({
+ implementation: MyCustomClassUsingTheUseCaseImpl,
+ dependencies: [CreateGroupUseCase]
+});
+
+export default MyCustomClassUsingTheUseCase;
+```
diff --git a/docs/developer-docs/6.0.x/headless-cms/use-case/model.ai.txt b/docs/developer-docs/6.0.x/headless-cms/use-case/model.ai.txt
new file mode 100644
index 000000000..5b34a2382
--- /dev/null
+++ b/docs/developer-docs/6.0.x/headless-cms/use-case/model.ai.txt
@@ -0,0 +1,130 @@
+AI Context: Model Use Cases (headless-cms/use-case/model.mdx)
+
+Source of Information:
+1. Analyzed use case patterns from group and entry use cases
+2. Examined model use case implementations
+3. Examined create, update, delete, get, list use cases
+4. Studied model-specific validation and business logic
+5. Understood field validation and model structure requirements
+
+Key Documentation Decisions:
+- Document all model-related use cases
+- Show abstraction creation pattern
+- Include implementation examples
+- Demonstrate repository integration
+- Show model-specific validations (fields, API names)
+- Include error handling with Result pattern
+- Cover CRUD operations comprehensively
+
+Use Cases Documented:
+1. Create Model - Create new content models
+2. Update Model - Modify existing models
+3. Delete Model - Remove models
+4. Get Model - Retrieve single model
+5. List Models - Query multiple models
+
+Pattern Used:
+- Interface definition
+- Error types (validation, authorization, repository errors)
+- createAbstraction call
+- Namespace export with all types
+- createImplementation pattern
+- Repository dependency injection
+- Result pattern for error handling
+- Model-specific validation (field structure, naming)
+- Authorization checks
+
+Model-Specific Validations:
+- Required field presence
+- API name format validation
+- Field structure validation
+- Duplicate field ID checks
+- Breaking change prevention
+
+Implementation Details:
+- Dependency injection of repositories
+- Complex validation logic
+- Type-safe implementations
+- Model structure validation
+- Field management
+
+Related Documents:
+- headless-cms/use-case/group.mdx - Group use cases (similar pattern)
+- headless-cms/use-case/entry.mdx - Entry use cases (similar pattern)
+- headless-cms/event-handler/model.mdx - Event integration
+- headless-cms/builder/model.mdx - Model builder
+- basic/di.mdx - Abstraction patterns
+
+Key Code Locations:
+- Use case implementations: Look for model-related use cases in the codebase
+
+To examine source code implementations in detail, access to the Webiny project repository is needed.
+
+Model Use Case Pattern:
+```typescript
+// 1. Interface
+export interface ICreateModelUseCase {
+ execute(input: CreateModelInput): Promise>;
+}
+
+// 2. Errors
+export interface ICreateModelUseCaseErrors {
+ notAuthorized: ModelNotAuthorizedError;
+ validation: ModelValidationError;
+ repository: RepositoryError;
+}
+type UseCaseError = ICreateModelUseCaseErrors[keyof ICreateModelUseCaseErrors];
+
+// 3. Abstraction
+export const CreateModelUseCase = createAbstraction("Cms/CreateModel");
+
+// 4. Namespace
+export namespace CreateModelUseCase {
+ export type Interface = ICreateModelUseCase;
+ export type Input = CreateModelInput;
+ export type Error = UseCaseError;
+ export type Return = Promise>;
+}
+```
+
+Use Cases to Document:
+1. Create Model - New model with field validation
+2. Update Model - Modify with breaking change checks
+3. Delete Model - Remove (check for entries)
+4. Get Model - Retrieve single model
+5. List Models - Query multiple models
+
+Model-Specific Validations:
+- Field structure validation (required fields)
+- API name format (singularApiName, pluralApiName)
+- Field type validation
+- Duplicate field ID checks
+- Breaking change detection (update)
+- Entry existence check (delete)
+
+Critical Validations:
+```typescript
+// API name validation
+if (!/^[A-Z][a-zA-Z0-9]*$/.test(input.singularApiName)) {
+ return Result.fail(new ValidationError("Invalid API name"));
+}
+
+// Field structure validation
+const hasIdField = input.fields.some(f => f.fieldId === "id");
+if (!hasIdField) {
+ return Result.fail(new ValidationError("Model must have 'id' field"));
+}
+
+// Before delete - check entries
+const entries = await context.cms.entries.list(model.modelId);
+if (entries.length > 0) {
+ return Result.fail(new ValidationError("Cannot delete model with entries"));
+}
+```
+
+Tone Guidelines:
+- Show model-specific validation complexity
+- Explain field structure requirements
+- Include breaking change considerations
+- Reference builder for model structure
+
diff --git a/docs/developer-docs/6.0.x/headless-cms/use-case/model.mdx b/docs/developer-docs/6.0.x/headless-cms/use-case/model.mdx
new file mode 100644
index 000000000..14a76d1d6
--- /dev/null
+++ b/docs/developer-docs/6.0.x/headless-cms/use-case/model.mdx
@@ -0,0 +1,192 @@
+---
+id: kq2numnh
+title: Model Use Cases
+description: About Headless CMS Model Use Cases
+---
+
+import {Alert} from "@/components/Alert";
+
+
+
+- What are available use cases for Headless CMS Models?
+- How to use them?
+
+
+
+## Overview
+This article will list all the use cases available for Headless CMS Models and explain how to use them.
+
+## Use Cases
+
+All use cases have an `execute` method that you can call to perform the action that use case is for.
+Params of that method and its return type are defined in the abstraction of the use case.
+
+Consult the examples below for more information.
+
+### Create Model Use Case
+
+```typescript extensions/cms/model/useCase/createModelUseCase.ts
+import { CreateModelUseCase } from "webiny/api/cms/model";
+import { ListGroupsUseCase } from "webiny/api/cms/group";
+import { CreateModel } from "./abstraction.js";
+
+class MyCustomClassUsingTheUseCaseImpl implements CreateModel.Interface {
+ public constructor(
+ private createModelUseCase: CreateModelUseCase.Interface,
+ private listGroupsUseCase: ListGroupsUseCase.Interface
+ ) {}
+
+ public async execute(params: CreateModel.Params): CreateModel.Return {
+ const groups = await this.listGroupsUseCase.execute();
+ if (groups.isFail()) {
+ throw new Error("Could not load groups.");
+ } else if (groups.value.length === 0) {
+ throw new Error("No groups found. Please create a group first.");
+ }
+ const group = groups.value[0];
+
+ const newModel = await this.createModelUseCase.execute({
+ name: params.name,
+ modelId: params.modelId,
+ singularApiName: params.singularApiName,
+ pluralApiName: params.pluralApiName,
+ group: group.slug,
+ fields: [],
+ layout: []
+ });
+ if (newModel.isFail()) {
+ throw new Error(newModel.error.message);
+ }
+ return newModel.value;
+ }
+}
+
+const MyCustomClassUsingTheUseCase = CreateModel.createImplementation({
+ implementation: MyCustomClassUsingTheUseCaseImpl,
+ dependencies: [CreateModelUseCase, ListGroupsUseCase]
+});
+
+export default MyCustomClassUsingTheUseCase;
+```
+
+### Create Model From Existing One Use Case
+
+```typescript extensions/cms/model/useCase/createModelFromUseCase.ts
+import {CreateModelFromUseCase} from "webiny/api/cms/model";
+import {ListGroupsUseCase} from "webiny/api/cms/group";
+import {CreateModelFrom} from "./abstraction.js";
+
+class MyCustomClassUsingTheUseCaseImpl implements CreateModelFrom.Interface {
+ public constructor(
+ private createModelFromUseCase: CreateModelFromUseCase.Interface,
+ private listGroupsUseCase: ListGroupsUseCase.Interface
+ ) {}
+
+ public async execute(params: CreateModelFrom.Params): CreateModelFrom.Return {
+ const groups = await this.listGroupsUseCase.execute();
+ if (groups.isFail()) {
+ throw new Error("Could not load groups.");
+ } else if (groups.value.length === 0) {
+ throw new Error("No groups found. Please create a group first.");
+ }
+ const group = groups.value[0];
+
+ const newModelFromExistingOne = await this.createModelFromUseCase.execute(
+ "originalModelId",
+ {
+ name: params.name,
+ modelId: params.modelId,
+ singularApiName: params.singularApiName,
+ pluralApiName: params.pluralApiName,
+ group: group.slug
+ }
+ );
+ if (newModelFromExistingOne.isFail()) {
+ throw new Error(newModelFromExistingOne.error.message);
+ }
+ return newModelFromExistingOne.value;
+ }
+}
+
+const MyCustomClassUsingTheUseCase = CreateModelFrom.createImplementation({
+ implementation: MyCustomClassUsingTheUseCaseImpl,
+ dependencies: [CreateModelFromUseCase, ListGroupsUseCase]
+});
+
+export default MyCustomClassUsingTheUseCase;
+```
+
+### Update Model Use Case
+
+```typescript extensions/cms/model/useCase/updateModelUseCase.ts
+import { GetModelUseCase, UpdateModelUseCase } from "webiny/api/cms/model";
+import { UpdateModel } from "./abstraction.js";
+
+class MyCustomClassUsingTheUseCaseImpl implements UpdateModel.Interface {
+ public constructor(
+ private updateModelUseCase: UpdateModelUseCase.Interface,
+ private getModelUseCase: GetModelUseCase.Interface
+ ) {}
+
+ public async execute(modelId: string, params: UpdateModel.Params): UpdateModel.Return {
+ const original = await this.getModelUseCase.execute(modelId);
+ if (original.isFail()) {
+ throw new Error(`Could not find model ${modelId}.`);
+ }
+ const model = original.value;
+
+ const newModel = await this.updateModelUseCase.execute(modelId, {
+ ...model,
+ ...params
+ });
+ if (newModel.isFail()) {
+ throw new Error(newModel.error.message);
+ }
+ return newModel.value;
+ }
+}
+
+const MyCustomClassUsingTheUseCase = UpdateModel.createImplementation({
+ implementation: MyCustomClassUsingTheUseCaseImpl,
+ dependencies: [UpdateModelUseCase, GetModelUseCase]
+});
+
+export default MyCustomClassUsingTheUseCase;
+```
+
+### Delete Model Use Case
+
+```typescript extensions/cms/model/useCase/deleteModelUseCase.ts
+import { DeleteModelUseCase, GetModelUseCase } from "webiny/api/cms/model";
+import { DeleteModel } from "./abstraction.js";
+
+class MyCustomClassUsingTheUseCaseImpl implements DeleteModel.Interface {
+ public constructor(
+ private deleteModelUseCase: DeleteModelUseCase.Interface,
+ private getModelUseCase: GetModelUseCase.Interface
+ ) {}
+
+ public async execute(modelId: string): DeleteModel.Return {
+ const original = await this.getModelUseCase.execute(modelId);
+ if (original.isFail()) {
+ throw new Error(`Could not find model ${modelId}.`);
+ }
+ const model = original.value;
+ const result = await this.deleteModelUseCase.execute(modelId);
+
+ if (result.isFail()) {
+ throw new Error(result.error.message);
+ }
+ return model;
+ }
+}
+
+const MyCustomClassUsingTheUseCase = DeleteModel.createImplementation({
+ implementation: MyCustomClassUsingTheUseCaseImpl,
+ dependencies: [DeleteModelUseCase, GetModelUseCase]
+});
+
+export default MyCustomClassUsingTheUseCase;
+
+
+```
diff --git a/docs/developer-docs/6.0.x/navigation.tsx b/docs/developer-docs/6.0.x/navigation.tsx
new file mode 100644
index 000000000..bacac97b7
--- /dev/null
+++ b/docs/developer-docs/6.0.x/navigation.tsx
@@ -0,0 +1,156 @@
+import React from "react";
+import { Group, NavigationRoot, Page, Separator } from "@webiny/docs-generator";
+
+export const Navigation = ({ children }: { children: React.ReactNode }) => {
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {/* __REFERENCE_PAGES_START__ */}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {/* __REFERENCE_PAGES_END__ */}
+
+
+
+
+ {children}
+
+ );
+};
diff --git a/docs/developer-docs/6.0.x/overview/features/security.mdx b/docs/developer-docs/6.0.x/overview/features/security.mdx
new file mode 100644
index 000000000..f4c0995f0
--- /dev/null
+++ b/docs/developer-docs/6.0.x/overview/features/security.mdx
@@ -0,0 +1,102 @@
+---
+id: aafeaacb
+title: Security
+description: Overview of Webiny security strategy.
+---
+
+import { Alert } from "@/components/Alert";
+
+
+
+- How we approach security
+- Additional security recommendations
+
+
+
+## About
+
+If we don't have security, we can't really say we have a good product. Although Webiny is a self-hosted solution, meaning you control your security, it's still important for us to provide an overview of our security practices. This will make you acquainted with our approach, and will make it easier to align your implementation to some of the best practices we established.
+
+This being an overview article, it will provide the main elements and a clear distinction in terms of the security responsibilities that are on your end in comparison to the ones being handled by Webiny.
+
+We've structured the article into 4 main sections:
+
+- **Codebase** - how we ensure our codebase isn't compromised
+- **Infrastructure** - how the security layer is implemented as part of the infrastructure that Webiny deploys
+- **Application** - how Webiny protects the application from unauthorized access
+- **Data** - how your data is stored and secured
+
+## Codebase
+
+Webiny, being an open-source project, our code is public, and with that comes great responsibility for the security aspects around it.
+
+Our code-base is regularly scanned for vulnerabilities by [CodeQL](https://securitylab.github.com/tools/codeql)—the world’s most powerful code analysis engine.
+
+All the 3rd party dependencies we use are scanned via [Dependabot](https://dependabot.com).
+
+No single change made to our codebase skips these checks.
+
+## Infrastructure
+
+Webiny is designed to run on top of the AWS cloud at the moment, with support for other clouds coming at a later point.
+
+
+The serverless services Webiny uses as part of its architecture are fault-tolerant by design. The only exception is Elasticsearch. In the Webiny production deployment stack, Elasticsearch is automatically deployed in multiple AZs, making it highly-available. Any public access, in both VPC and non-VPC deployment is restricted.
+
+With Webiny there are zero servers you need to manage, reducing the risk of a security breach due to misconfiguration. Serverless services are tested by the cloud provider against all forms of attacks across millions of customers, giving your confidence in their security. Serverless services in general reduce the potential attack vectors that can be used against your application.
+
+Webiny ships with 2 infrastructure stacks by default, a development one and a production one.
+
+
+
+We highly recommend that you use the production stack for all your projects running production traffic.
+
+
+
+The production stack by default is deployed inside a private VPC preventing direct access to resources like DynamoDB and the Elasticsearch database. Keeping your data safe.
+
+Additional security improvements you can make to your project:
+
+- **Firewall**: Webiny intentionally deploys a CloudFront web distribution in front of an API Gateway. This setup allows you to place a web application firewall to all incoming requests for added security.
+
+## Application
+
+Webiny is built to support different authentication mechanisms. Out of the box, it is configured to work with [AWS Cognito](https://aws.amazon.com/cognito/), an enterprise-grade, battle-tested identity provider. The framework, however, supports any identity provider, by means of plugins.
+
+Webiny draws a very clear line between **authentication** and **authorization**. We rely on third-party IdPs for authentication and use a very flexible system of permissions for authorization.
+
+Authorization is usually very closely tied to business logic, so using scopes from the JWT, or simple string-based roles is not enough for complex business applications. To allow different types of integration, we provide a very thin security framework, based on plugins. On top of that, we define permissions as rich objects with different application-related properties.
+
+## Data
+
+Because Webiny is self-hosted and under the MIT license, your data stays within your cloud infrastructure. In practice, this usually means there is no need for any legal, data compliance or GDPR changes to be made when adopting Webiny.
+
+When it comes to storing your data, it's saved inside a DynamoDB database and Elasticsearch, and files are stored inside an S3 bucket.
+
+All the data inside DynamoDB is encrypted in transit and at rest by default.
+
+All the data inside Elasticsearch is encrypted at transit only, by default.
+
+
+
+For production cases, we recommend you also encrypt data at rest in Elasticsearch. Ensure you have a proper key management strategy in place beforehand otherwise it could lead to making your data inaccessible. For more info visit: https://docs.aws.amazon.com/elasticsearch-service/latest/developerguide/encryption-at-rest.html
+
+
+
+The data inside S3 bucket by default is not encrypted, is set to be publicly accessible and versioning is turned off. Public access is only allowed on the `list` command. Write operations need to be signed with a security token to be allowed. We advise that you adjust these parameters to the needs of your project accordingly.
+
+
+
+If needed you can restrict access to the S3 buckets by modifying the ACL policy inside the Pulumi infrastructure files. At the moment if you make the S3 bucket private to non-authorized users, images embedded in the Page Builder and other places will not be displayed and potentially the Admin app might be made inaccessible. Please contact us in case you need to make your S3 completely private.
+
+
+
+## FAQ
+
+### Can I use a different identity provider?
+
+Yes, absolutely. The default IdP implementation contains a set of plugins on the API and React sides. All you need to do is follow the same principle and implement your own plugins that will work with the IdP of your choice.
+
+### Can I roll my own authentication system instead of using a third-party IdP?
+
+We don't recommend it, but yes, you can. Following the same implementation strategy that comes with Webiny by default, you can create all kinds of authentication mechanisms.
diff --git a/docs/developer-docs/6.0.x/overview/pricing.mdx b/docs/developer-docs/6.0.x/overview/pricing.mdx
new file mode 100644
index 000000000..0b730f2d8
--- /dev/null
+++ b/docs/developer-docs/6.0.x/overview/pricing.mdx
@@ -0,0 +1,66 @@
+---
+id: aafeab41
+title: Pricing Tiers
+description: How is Webiny priced and what are the available options.
+---
+
+import { Alert } from "@/components/Alert";
+
+
+
+- What is Webiny's business model?
+- What is commercial open-source software?
+- What are the different Webiny pricing tiers?
+
+
+
+Webiny is an open-source project and at such, all our code is open to the public on our [GitHub repository](https://github.com/webiny/webiny-js). However building an open-source project and a business, in the past have been two different things. But lately, they have come together into what's today known as Commercial Open Source Software (COSS) and this is the model Webiny as a project has embraced.
+
+
+
+Here's is a great article on the topic of Commercial Open-Source:
+https://www.webiny.com/blog/what-is-commercial-open-source
+
+
+
+## Webiny's Dual License Model
+
+Majority of Webiny's code base (over 95%) is licensed under the MIT open-source license. As such, you are given the right to use that code for any type of use-cases, projects, be commercial or not. You're allowed to make changes to the project and you can even resell it if you want to. We are a strong believer that open-source is the only way software will be written and distributed in the future and we are commited to such a cause ourselves.
+
+However, as a fairly young company we need to ensure the long-term success of our project. Webiny is already a large project, and it's growing. As such it requires a dedicated team working full time to maintain, build and fix things, alongside the contributions coming from the community. To ensure their long-term sustainability, many open-source projects add a commercial aspect to their project.
+
+This is usually done through either offering a cloud version, or a dual-license offering. Certain features might not be available under the free OSS license, but instead under a commercial license. Which might, or might not, be open-source. **It's important to distiguish that open-source doesn't mean "free"**. If only means the code is open for public to view, modify and enhance. Still to use the code, the user must adhear to the terms of the license.
+
+
+
+What is open-source? https://opensource.com/resources/what-open-source
+
+
+
+Alongside the MIT license, Webiny also has a commercial license that comes with a cost, which unlocks additional features and functionality within the system. The revenue we get from this license is directly reinvested into building more features, and making the platform better and enjoyable to use. This is how we are building a sustainable model around our business, and ensuring the long-term development of our project.
+
+## Webiny Pricing Tiers
+
+Webiny comes in these three pricing tiers:
+
+- **Free**
+ - for personal and hobby projects
+ - has only basic security options
+ - doesn't support multi-tenancy
+ - all code is licensed under the MIT open-source license
+ - 100% free to use without any restrictions
+- **Business**
+ - for small team projects
+ - supports advanced roles and permissions
+ - supports optional addons such as Publishing Workflow and Headless Pages
+ - supports multi-tenancy
+ - all the code is open-source, but it's a mix of the MIT license and the Webiny's commerical license, users are allowed to make modifications to the code regardless of the license
+ - price starts at $9 user/month, first user is free
+- **Enterprise**
+ - for teams working on critical projects
+ - comes with SSO and team management
+ - includes SLA support and consultancy services
+ - all the code is open-source, but it's a mix of the MIT license and the Webiny's commerical license, users are allowed to make modifications to the code regardless of the license
+ - price starts at $3,499 / month
+
+For more details on the pricing tier, please visit our [pricing page](https://www.webiny.com/pricing). For any additional questions, please email us at [sales@webiny.com](mailto:sales@webiny.com).
diff --git a/docs/developer-docs/6.0.x/reference/admin.ai.txt b/docs/developer-docs/6.0.x/reference/admin.ai.txt
new file mode 100644
index 000000000..656e3a84a
--- /dev/null
+++ b/docs/developer-docs/6.0.x/reference/admin.ai.txt
@@ -0,0 +1,28 @@
+AI Context: Admin (reference/admin.mdx)
+
+Source of Information:
+1. packages/webiny/src/admin.ts — barrel re-export file
+2. /Users/adrian/dev/wby-next/packages/app/src/shared/di/useFeature.ts — originating source
+3. /Users/adrian/dev/wby-next/packages/app/src/errors/index.ts — originating source
+4. /Users/adrian/dev/wby-next/packages/app-admin/src/permissions/index.ts — originating source
+5. /Users/adrian/dev/wby-next/packages/app-admin/src/features/buildParams/index.ts — originating source
+
+Key Documentation Decisions:
+- This file is auto-generated by scripts/generate-reference.ts — do not edit manually
+- Symbols are documented in the order they appear in the barrel file
+- Declaration text is extracted from the TypeScript AST; method bodies are stripped
+- Type-only exports are labeled as "Type"; namespace exports include member listings
+
+Exported Symbols:
+useFeature, NetworkErrorEventHandler, createPermissionSchema, createHasPermission, createUsePermissions, BuildParam, BuildParams
+
+Import Path: webiny/admin
+
+Related Documents:
+- docs/developer-docs/6.0.x/basic/di.mdx — DI pattern used by all abstractions
+- docs/developer-docs/6.0.x/basic/result.mdx — Result type used in use case returns
+
+Tone Guidelines:
+- This is a reference page — terse, API-focused, no prose beyond what's necessary
+- Code blocks are the primary content; descriptions serve only to clarify intent
+- Do not add analogies or long explanations — link to guide pages for those
diff --git a/docs/developer-docs/6.0.x/reference/admin.mdx b/docs/developer-docs/6.0.x/reference/admin.mdx
new file mode 100644
index 000000000..53b845e6b
--- /dev/null
+++ b/docs/developer-docs/6.0.x/reference/admin.mdx
@@ -0,0 +1,222 @@
+---
+id: ywrtaw40
+title: Admin
+description: "Admin app core: createFeature, createAbstraction, Provider, Plugin"
+---
+
+import { Alert } from "@/components/Alert";
+import { SymbolList } from "@/components/SymbolList";
+
+
+
+- Which event handlers can you implement?
+- How to import and use each exported item?
+
+
+
+## Overview
+
+This page documents everything exported from `webiny/admin`. Import any of the items below directly from this path in your Webiny extensions.
+
+**Hooks**
+
+
+
+**Other**
+
+
+
+## Hooks
+
+### `useFeature`
+
+**Function** — imported from `webiny/admin`
+
+```typescript
+import { useFeature } from "webiny/admin";
+```
+
+```typescript
+export function useFeature(feature: FeatureDefinition): TExports;
+```
+
+## Other
+
+### `BuildParam`
+
+**Abstraction** — imported from `webiny/admin`
+
+```typescript
+import { BuildParam } from "webiny/admin";
+```
+
+**Interface `BuildParam.Interface`:**
+
+```typescript
+interface BuildParam.Interface {
+ key: string;
+ value: any;
+}
+```
+
+**Types:**
+
+```typescript
+namespace BuildParam {
+ type Interface = IBuildParam;
+}
+```
+
+**Usage:**
+
+```typescript extensions/MyImpl.ts
+import { BuildParam } from "webiny/admin";
+
+class MyImpl implements MyUseCase.Interface {
+ public constructor(private buildParam: BuildParam.Interface) {}
+
+ public async execute(/* ... */): Promise {
+ this.buildParam.key: string(/* ... */);
+ }
+}
+
+export default MyUseCase.createImplementation({
+ implementation: MyImpl,
+ dependencies: [BuildParam]
+});
+```
+
+### `BuildParams`
+
+**Abstraction** — imported from `webiny/admin`
+
+```typescript
+import { BuildParams } from "webiny/admin";
+```
+
+**Interface `BuildParams.Interface`:**
+
+```typescript
+interface BuildParams.Interface {
+ get(key: string): T | null;
+}
+```
+
+**Types:**
+
+```typescript
+namespace BuildParams {
+ type Interface = IBuildParams;
+}
+```
+
+**Usage:**
+
+```typescript extensions/MyImpl.ts
+import { BuildParams } from "webiny/admin";
+
+class MyImpl implements MyUseCase.Interface {
+ public constructor(private buildParams: BuildParams.Interface) {}
+
+ public async execute(/* ... */): Promise {
+ this.buildParams.get(/* ... */);
+ }
+}
+
+export default MyUseCase.createImplementation({
+ implementation: MyImpl,
+ dependencies: [BuildParams]
+});
+```
+
+### `createHasPermission`
+
+**Function** — imported from `webiny/admin`
+
+```typescript
+import { createHasPermission } from "webiny/admin";
+```
+
+```typescript
+export function createHasPermission(
+ schema: S
+): React.FC>;
+```
+
+### `createPermissionSchema`
+
+**Function** — imported from `webiny/admin`
+
+```typescript
+import { createPermissionSchema } from "webiny/admin";
+```
+
+```typescript
+export function createPermissionSchema(config: T): T;
+```
+
+### `createUsePermissions`
+
+**Function** — imported from `webiny/admin`
+
+```typescript
+import { createUsePermissions } from "webiny/admin";
+```
+
+```typescript
+export function createUsePermissions(
+ schema: S
+): () => UsePermissionsResult;
+```
+
+### `NetworkErrorEventHandler`
+
+**Event Handler Abstraction** — imported from `webiny/admin`
+
+```typescript
+import { NetworkErrorEventHandler } from "webiny/admin";
+```
+
+**Interface `NetworkErrorEventHandler.Interface`:**
+
+```typescript
+interface NetworkErrorEventHandler.Interface {
+ handle(event: NetworkErrorEvent): Promise;
+}
+```
+
+**Types:**
+
+```typescript
+namespace NetworkErrorEventHandler {
+ type Interface = IEventHandler;
+}
+```
+
+**Usage:**
+
+```typescript extensions/MyHandler.ts
+import { NetworkErrorEventHandler } from "webiny/admin";
+
+class MyHandler implements NetworkErrorEventHandler.Interface {
+ public constructor(/* inject dependencies here */) {}
+
+ public async handle(event: NetworkErrorEventHandler.Event): Promise {
+ // implementation
+ }
+}
+
+export default NetworkErrorEventHandler.createImplementation({
+ implementation: MyHandler,
+ dependencies: []
+});
+```
diff --git a/docs/developer-docs/6.0.x/reference/admin/aco.ai.txt b/docs/developer-docs/6.0.x/reference/admin/aco.ai.txt
new file mode 100644
index 000000000..735f21b6d
--- /dev/null
+++ b/docs/developer-docs/6.0.x/reference/admin/aco.ai.txt
@@ -0,0 +1,26 @@
+AI Context: ACO (reference/admin/aco.mdx)
+
+Source of Information:
+1. packages/webiny/src/admin/aco.ts — barrel re-export file
+2. /Users/adrian/dev/wby-next/packages/app-aco/src/hooks/useRecords.ts — originating source
+3. /Users/adrian/dev/wby-next/packages/app-aco/src/hooks/useNavigateFolder.ts — originating source
+
+Key Documentation Decisions:
+- This file is auto-generated by scripts/generate-reference.ts — do not edit manually
+- Symbols are documented in the order they appear in the barrel file
+- Declaration text is extracted from the TypeScript AST; method bodies are stripped
+- Type-only exports are labeled as "Type"; namespace exports include member listings
+
+Exported Symbols:
+useRecords, useNavigateFolder
+
+Import Path: webiny/admin/aco
+
+Related Documents:
+- docs/developer-docs/6.0.x/basic/di.mdx — DI pattern used by all abstractions
+- docs/developer-docs/6.0.x/basic/result.mdx — Result type used in use case returns
+
+Tone Guidelines:
+- This is a reference page — terse, API-focused, no prose beyond what's necessary
+- Code blocks are the primary content; descriptions serve only to clarify intent
+- Do not add analogies or long explanations — link to guide pages for those
diff --git a/docs/developer-docs/6.0.x/reference/admin/aco.mdx b/docs/developer-docs/6.0.x/reference/admin/aco.mdx
new file mode 100644
index 000000000..36e32fb1a
--- /dev/null
+++ b/docs/developer-docs/6.0.x/reference/admin/aco.mdx
@@ -0,0 +1,72 @@
+---
+id: ywrtaw4v
+title: ACO
+description: "ACO (Advanced Content Organisation) hooks and utilities"
+---
+
+import { Alert } from "@/components/Alert";
+import { SymbolList } from "@/components/SymbolList";
+
+
+
+- What is exported from `webiny/admin/aco`?
+- How to import and use each exported item?
+
+
+
+## Overview
+
+This page documents everything exported from `webiny/admin/aco`. Import any of the items below directly from this path in your Webiny extensions.
+
+
+
+## `useNavigateFolder`
+
+**Constant** — imported from `webiny/admin/aco`
+
+```typescript
+import { useNavigateFolder } from "webiny/admin/aco";
+```
+
+```typescript
+export const useNavigateFolder = () => {
+ const context = useContext(NavigateFolderContext);
+ if (!context) {
+ throw new Error("useNavigateFolder must be used within a NavigateFolderContext");
+ }
+
+ return context;
+};
+```
+
+## `useRecords`
+
+**Constant** — imported from `webiny/admin/aco`
+
+```typescript
+import { useRecords } from "webiny/admin/aco";
+```
+
+```typescript
+export const useRecords = makeDecoratable((folderId?: string) => {
+ const context = useContext(SearchRecordsContext);
+
+ if (!context) {
+ throw new Error("useSearchRecords must be used within a SearchRecordsContext");
+ }
+
+ const { folderIdPath } = useAcoApp();
+
+ const { currentFolderId } = useNavigateFolder();
+
+ const {
+ records,
+ loading,
+ meta,
+
+```
diff --git a/docs/developer-docs/6.0.x/reference/admin/build-params.ai.txt b/docs/developer-docs/6.0.x/reference/admin/build-params.ai.txt
new file mode 100644
index 000000000..e0c8f90e5
--- /dev/null
+++ b/docs/developer-docs/6.0.x/reference/admin/build-params.ai.txt
@@ -0,0 +1,25 @@
+AI Context: Build Params (reference/admin/build-params.mdx)
+
+Source of Information:
+1. packages/webiny/src/admin/build-params.ts — barrel re-export file
+2. /Users/adrian/dev/wby-next/packages/app-admin/src/features/buildParams/index.ts — originating source
+
+Key Documentation Decisions:
+- This file is auto-generated by scripts/generate-reference.ts — do not edit manually
+- Symbols are documented in the order they appear in the barrel file
+- Declaration text is extracted from the TypeScript AST; method bodies are stripped
+- Type-only exports are labeled as "Type"; namespace exports include member listings
+
+Exported Symbols:
+BuildParam, BuildParams
+
+Import Path: webiny/admin/build-params
+
+Related Documents:
+- docs/developer-docs/6.0.x/basic/di.mdx — DI pattern used by all abstractions
+- docs/developer-docs/6.0.x/basic/result.mdx — Result type used in use case returns
+
+Tone Guidelines:
+- This is a reference page — terse, API-focused, no prose beyond what's necessary
+- Code blocks are the primary content; descriptions serve only to clarify intent
+- Do not add analogies or long explanations — link to guide pages for those
diff --git a/docs/developer-docs/6.0.x/reference/admin/build-params.mdx b/docs/developer-docs/6.0.x/reference/admin/build-params.mdx
new file mode 100644
index 000000000..c0ea63ccf
--- /dev/null
+++ b/docs/developer-docs/6.0.x/reference/admin/build-params.mdx
@@ -0,0 +1,113 @@
+---
+id: ywrtaw4v
+title: Build Params
+description: "Reference for webiny/admin/build-params"
+---
+
+import { Alert } from "@/components/Alert";
+import { SymbolList } from "@/components/SymbolList";
+
+
+
+- What is exported from `webiny/admin/build-params`?
+- How to import and use each exported item?
+
+
+
+## Overview
+
+This page documents everything exported from `webiny/admin/build-params`. Import any of the items below directly from this path in your Webiny extensions.
+
+
+
+## `BuildParam`
+
+**Abstraction** — imported from `webiny/admin/build-params`
+
+```typescript
+import { BuildParam } from "webiny/admin/build-params";
+```
+
+**Interface `BuildParam.Interface`:**
+
+```typescript
+interface BuildParam.Interface {
+ key: string;
+ value: any;
+}
+```
+
+**Types:**
+
+```typescript
+namespace BuildParam {
+ type Interface = IBuildParam;
+}
+```
+
+**Usage:**
+
+```typescript extensions/MyImpl.ts
+import { BuildParam } from "webiny/admin/build-params";
+
+class MyImpl implements MyUseCase.Interface {
+ public constructor(private buildParam: BuildParam.Interface) {}
+
+ public async execute(/* ... */): Promise {
+ this.buildParam.key: string(/* ... */);
+ }
+}
+
+export default MyUseCase.createImplementation({
+ implementation: MyImpl,
+ dependencies: [BuildParam]
+});
+```
+
+## `BuildParams`
+
+**Abstraction** — imported from `webiny/admin/build-params`
+
+```typescript
+import { BuildParams } from "webiny/admin/build-params";
+```
+
+**Interface `BuildParams.Interface`:**
+
+```typescript
+interface BuildParams.Interface {
+ get(key: string): T | null;
+}
+```
+
+**Types:**
+
+```typescript
+namespace BuildParams {
+ type Interface = IBuildParams;
+}
+```
+
+**Usage:**
+
+```typescript extensions/MyImpl.ts
+import { BuildParams } from "webiny/admin/build-params";
+
+class MyImpl implements MyUseCase.Interface {
+ public constructor(private buildParams: BuildParams.Interface) {}
+
+ public async execute(/* ... */): Promise {
+ this.buildParams.get(/* ... */);
+ }
+}
+
+export default MyUseCase.createImplementation({
+ implementation: MyImpl,
+ dependencies: [BuildParams]
+});
+```
diff --git a/docs/developer-docs/6.0.x/reference/admin/buildParams.ai.txt b/docs/developer-docs/6.0.x/reference/admin/buildParams.ai.txt
new file mode 100644
index 000000000..129386644
--- /dev/null
+++ b/docs/developer-docs/6.0.x/reference/admin/buildParams.ai.txt
@@ -0,0 +1,25 @@
+AI Context: Build Params (reference/admin/buildParams.mdx)
+
+Source of Information:
+1. packages/webiny/src/admin/buildParams.ts — barrel re-export file
+2. /Users/adrian/dev/wby-next/packages/app-admin/src/features/buildParams/index.ts — originating source
+
+Key Documentation Decisions:
+- This file is auto-generated by scripts/generate-reference.ts — do not edit manually
+- Symbols are documented in the order they appear in the barrel file
+- Declaration text is extracted from the TypeScript AST; method bodies are stripped
+- Type-only exports are labeled as "Type"; namespace exports include member listings
+
+Exported Symbols:
+BuildParam, BuildParams
+
+Import Path: webiny/admin/buildParams
+
+Related Documents:
+- docs/developer-docs/6.0.x/basic/di.mdx — DI pattern used by all abstractions
+- docs/developer-docs/6.0.x/basic/result.mdx — Result type used in use case returns
+
+Tone Guidelines:
+- This is a reference page — terse, API-focused, no prose beyond what's necessary
+- Code blocks are the primary content; descriptions serve only to clarify intent
+- Do not add analogies or long explanations — link to guide pages for those
diff --git a/docs/developer-docs/6.0.x/reference/admin/buildParams.mdx b/docs/developer-docs/6.0.x/reference/admin/buildParams.mdx
new file mode 100644
index 000000000..a3fd1fabb
--- /dev/null
+++ b/docs/developer-docs/6.0.x/reference/admin/buildParams.mdx
@@ -0,0 +1,115 @@
+---
+id: ywrtaw4v
+title: Build Params
+description: "Admin build parameter types"
+---
+
+import { Alert } from "@/components/Alert";
+import { SymbolList } from "@/components/SymbolList";
+
+
+
+- What is exported from `webiny/admin/buildParams`?
+- How to import and use each exported item?
+
+
+
+## Overview
+
+This page documents everything exported from `webiny/admin/buildParams`. Import any of the items below directly from this path in your Webiny extensions.
+
+
+
+## `BuildParam`
+
+**Abstraction** — imported from `webiny/admin/buildParams`
+
+```typescript
+import { BuildParam } from "webiny/admin/buildParams";
+```
+
+**Interface `BuildParam.Interface`:**
+
+```typescript
+interface BuildParam.Interface {
+ key: string;
+ value: any;
+}
+```
+
+**Types:**
+
+```typescript
+namespace BuildParam {
+ type Interface = IBuildParam;
+}
+```
+
+**Usage:**
+
+```typescript
+// extensions/MyImpl.ts
+import { BuildParam } from "webiny/admin/buildParams";
+
+class MyImpl implements MyUseCase.Interface {
+ public constructor(private buildParam: BuildParam.Interface) {}
+
+ public async execute(/* ... */): Promise {
+ this.buildParam.key: string(/* ... */);
+ }
+}
+
+export default MyUseCase.createImplementation({
+ implementation: MyImpl,
+ dependencies: [BuildParam]
+});
+```
+
+## `BuildParams`
+
+**Abstraction** — imported from `webiny/admin/buildParams`
+
+```typescript
+import { BuildParams } from "webiny/admin/buildParams";
+```
+
+**Interface `BuildParams.Interface`:**
+
+```typescript
+interface BuildParams.Interface {
+ get(key: string): T | null;
+}
+```
+
+**Types:**
+
+```typescript
+namespace BuildParams {
+ type Interface = IBuildParams;
+}
+```
+
+**Usage:**
+
+```typescript
+// extensions/MyImpl.ts
+import { BuildParams } from "webiny/admin/buildParams";
+
+class MyImpl implements MyUseCase.Interface {
+ public constructor(private buildParams: BuildParams.Interface) {}
+
+ public async execute(/* ... */): Promise {
+ this.buildParams.get(/* ... */);
+ }
+}
+
+export default MyUseCase.createImplementation({
+ implementation: MyImpl,
+ dependencies: [BuildParams]
+});
+```
diff --git a/docs/developer-docs/6.0.x/reference/admin/cms.ai.txt b/docs/developer-docs/6.0.x/reference/admin/cms.ai.txt
new file mode 100644
index 000000000..9c71a89d5
--- /dev/null
+++ b/docs/developer-docs/6.0.x/reference/admin/cms.ai.txt
@@ -0,0 +1,31 @@
+AI Context: CMS (reference/admin/cms.mdx)
+
+Source of Information:
+1. packages/webiny/src/admin/cms.ts — barrel re-export file
+2. /Users/adrian/dev/wby-next/packages/app-headless-cms/src/admin/hooks/useQuery.ts — originating source
+3. /Users/adrian/dev/wby-next/packages/app-headless-cms/src/admin/hooks/useLazyQuery.ts — originating source
+4. /Users/adrian/dev/wby-next/packages/app-headless-cms/src/admin/hooks/useMutation.ts — originating source
+5. /Users/adrian/dev/wby-next/packages/app-headless-cms/src/admin/components/ModelProvider/index.ts — originating source
+6. /Users/adrian/dev/wby-next/packages/app-headless-cms/src/admin/hooks/usePermission.ts — originating source
+7. /Users/adrian/dev/wby-next/packages/app-headless-cms/src/routes.ts — originating source
+8. /Users/adrian/dev/wby-next/packages/app-headless-cms-common/src/types/index.ts — originating source
+
+Key Documentation Decisions:
+- This file is auto-generated by scripts/generate-reference.ts — do not edit manually
+- Symbols are documented in the order they appear in the barrel file
+- Declaration text is extracted from the TypeScript AST; method bodies are stripped
+- Type-only exports are labeled as "Type"; namespace exports include member listings
+
+Exported Symbols:
+useQuery, useLazyQuery, useMutation, useModel, usePermission, Routes, CmsContentEntry, CmsModel, CmsModelField, CmsIdentity, CmsLayoutFieldTypePlugin, CmsLayoutDescriptorRendererPlugin, CmsBaseLayoutDescriptor, CmsLayoutDescriptor
+
+Import Path: webiny/admin/cms
+
+Related Documents:
+- docs/developer-docs/6.0.x/basic/di.mdx — DI pattern used by all abstractions
+- docs/developer-docs/6.0.x/basic/result.mdx — Result type used in use case returns
+
+Tone Guidelines:
+- This is a reference page — terse, API-focused, no prose beyond what's necessary
+- Code blocks are the primary content; descriptions serve only to clarify intent
+- Do not add analogies or long explanations — link to guide pages for those
diff --git a/docs/developer-docs/6.0.x/reference/admin/cms.mdx b/docs/developer-docs/6.0.x/reference/admin/cms.mdx
new file mode 100644
index 000000000..7ed0fdf57
--- /dev/null
+++ b/docs/developer-docs/6.0.x/reference/admin/cms.mdx
@@ -0,0 +1,295 @@
+---
+id: ywrtaw4v
+title: CMS
+description: "CMS admin hooks, types and utilities"
+---
+
+import { Alert } from "@/components/Alert";
+import { SymbolList } from "@/components/SymbolList";
+
+
+
+- What is exported from `webiny/admin/cms`?
+- How to import and use each exported item?
+
+
+
+## Overview
+
+This page documents everything exported from `webiny/admin/cms`. Import any of the items below directly from this path in your Webiny extensions.
+
+**Components**
+
+
+
+**Hooks**
+
+
+
+**Types**
+
+
+
+## Components
+
+### `Routes`
+
+**Constant** — imported from `webiny/admin/cms`
+
+```typescript
+import { Routes } from "webiny/admin/cms";
+```
+
+```typescript
+export const Routes = {
+ ContentModelGroups: {
+ List: new Route({
+ name: "Cms/ContentModelGroups/List",
+ path: "/cms/content-model-groups",
+ params: zod => {
+ return {
+ id: zod.string().optional(),
+ new: zod.boolean().optional()
+ };
+ }
+ })
+ },
+
+ ContentEntries: {
+
+```
+
+## Hooks
+
+### `useLazyQuery`
+
+**Constant** — imported from `webiny/admin/cms`
+
+```typescript
+import { useLazyQuery } from "webiny/admin/cms";
+```
+
+```typescript
+export const useLazyQuery = function (
+ query: DocumentNode,
+ options: LazyQueryHookOptions = {}
+): QueryTuple {
+ const { apolloClient } = useCms();
+
+ return apolloUseLazyQuery(query, {
+ client: apolloClient,
+ ...options
+ });
+};
+```
+
+### `useModel`
+
+**Function** — imported from `webiny/admin/cms`
+
+Get model from the current context.
+
+```typescript
+import { useModel } from "webiny/admin/cms";
+```
+
+```typescript
+export function useModel(): UseModelReturnType;
+```
+
+### `useMutation`
+
+**Constant** — imported from `webiny/admin/cms`
+
+```typescript
+import { useMutation } from "webiny/admin/cms";
+```
+
+```typescript
+export const useMutation = function (
+ mutation: DocumentNode,
+ options: MutationHookOptions = {}
+): MutationTuple {
+ const { apolloClient } = useCms();
+
+ return apolloUseMutation(mutation, {
+ client: apolloClient,
+ ...options
+ });
+};
+```
+
+### `usePermission`
+
+**Constant** — imported from `webiny/admin/cms`
+
+```typescript
+import { usePermission } from "webiny/admin/cms";
+```
+
+```typescript
+export const usePermission = makeDecoratable(() => {
+ const { identity } = useIdentity();
+
+ const hasFullAccess = useMemo(() => !!identity.getPermission("cms.*"), [identity]);
+
+ const canRead = useCallback(
+ (permissionName: string): boolean => {
+ if (hasFullAccess) {
+ return true;
+ }
+ const permissions =
+ identity.getP
+```
+
+### `useQuery`
+
+**Constant** — imported from `webiny/admin/cms`
+
+```typescript
+import { useQuery } from "webiny/admin/cms";
+```
+
+```typescript
+export const useQuery = function (
+ query: DocumentNode,
+ options: QueryHookOptions = {}
+): QueryResult {
+ const { apolloClient } = useCms();
+
+ return apolloUseQuery(query, {
+ client: apolloClient,
+ skip: !apolloClient,
+ ...options
+ });
+};
+```
+
+## Types
+
+### `CmsBaseLayoutDescriptor`
+
+**Type** — imported from `webiny/admin/cms`
+
+```typescript
+import type { CmsBaseLayoutDescriptor } from "webiny/admin/cms";
+```
+
+```typescript
+export interface CmsBaseLayoutDescriptor {
+ id: string;
+ type: string;
+ rules?: FieldRule[];
+}
+```
+
+### `CmsContentEntry`
+
+**Type** — imported from `webiny/admin/cms`
+
+```typescript
+import type { CmsContentEntry } from "webiny/admin/cms";
+```
+
+```typescript
+export interface CmsContentEntry { ... }
+```
+
+### `CmsIdentity`
+
+**Type** — imported from `webiny/admin/cms`
+
+```typescript
+import type { CmsIdentity } from "webiny/admin/cms";
+```
+
+```typescript
+export interface CmsIdentity {
+ id: string;
+ displayName: string;
+ type: string;
+}
+```
+
+### `CmsLayoutDescriptor`
+
+**Type** — imported from `webiny/admin/cms`
+
+```typescript
+import type { CmsLayoutDescriptor } from "webiny/admin/cms";
+```
+
+```typescript
+export type CmsLayoutDescriptor =
+ | CmsSeparatorLayoutDescriptor
+ | CmsAlertLayoutDescriptor
+ | CmsTabLayoutDescriptor
+ | CmsBaseLayoutDescriptor;
+```
+
+### `CmsLayoutDescriptorRendererPlugin`
+
+**Type** — imported from `webiny/admin/cms`
+
+```typescript
+import type { CmsLayoutDescriptorRendererPlugin } from "webiny/admin/cms";
+```
+
+```typescript
+export interface CmsLayoutDescriptorRendererPlugin extends Plugin { ... }
+```
+
+### `CmsLayoutFieldTypePlugin`
+
+**Type** — imported from `webiny/admin/cms`
+
+```typescript
+import type { CmsLayoutFieldTypePlugin } from "webiny/admin/cms";
+```
+
+```typescript
+export interface CmsLayoutFieldTypePlugin extends Plugin { ... }
+```
+
+### `CmsModel`
+
+**Type** — imported from `webiny/admin/cms`
+
+```typescript
+import type { CmsModel } from "webiny/admin/cms";
+```
+
+```typescript
+export interface CmsModel { ... }
+```
+
+### `CmsModelField`
+
+**Type** — imported from `webiny/admin/cms`
+
+```typescript
+import type { CmsModelField } from "webiny/admin/cms";
+```
+
+```typescript
+export type CmsModelField = T & { ... };
+```
diff --git a/docs/developer-docs/6.0.x/reference/admin/cms/entry/editor.ai.txt b/docs/developer-docs/6.0.x/reference/admin/cms/entry/editor.ai.txt
new file mode 100644
index 000000000..5fd4c6d9b
--- /dev/null
+++ b/docs/developer-docs/6.0.x/reference/admin/cms/entry/editor.ai.txt
@@ -0,0 +1,28 @@
+AI Context: Editor (reference/admin/cms/entry/editor.mdx)
+
+Source of Information:
+1. packages/webiny/src/admin/cms/entry/editor.ts — barrel re-export file
+2. /Users/adrian/dev/wby-next/packages/app-headless-cms/src/admin/components/ContentEntryForm/useContentEntryForm.ts — originating source
+3. /Users/adrian/dev/wby-next/packages/app-headless-cms/src/admin/views/contentEntries/hooks/index.ts — originating source
+4. /Users/adrian/dev/wby-next/packages/app-headless-cms/src/admin/config/contentEntries/index.ts — originating source
+5. /Users/adrian/dev/wby-next/packages/app-headless-cms/src/admin/views/contentEntries/hooks/useSingletonContentEntry.ts — originating source
+
+Key Documentation Decisions:
+- This file is auto-generated by scripts/generate-reference.ts — do not edit manually
+- Symbols are documented in the order they appear in the barrel file
+- Declaration text is extracted from the TypeScript AST; method bodies are stripped
+- Type-only exports are labeled as "Type"; namespace exports include member listings
+
+Exported Symbols:
+useContentEntryForm, useContentEntryEditor, ContentEntryEditorConfig, useSingleEntryContentEntry
+
+Import Path: webiny/admin/cms/entry/editor
+
+Related Documents:
+- docs/developer-docs/6.0.x/basic/di.mdx — DI pattern used by all abstractions
+- docs/developer-docs/6.0.x/basic/result.mdx — Result type used in use case returns
+
+Tone Guidelines:
+- This is a reference page — terse, API-focused, no prose beyond what's necessary
+- Code blocks are the primary content; descriptions serve only to clarify intent
+- Do not add analogies or long explanations — link to guide pages for those
diff --git a/docs/developer-docs/6.0.x/reference/admin/cms/entry/editor.mdx b/docs/developer-docs/6.0.x/reference/admin/cms/entry/editor.mdx
new file mode 100644
index 000000000..73fea49b7
--- /dev/null
+++ b/docs/developer-docs/6.0.x/reference/admin/cms/entry/editor.mdx
@@ -0,0 +1,113 @@
+---
+id: ywrtaw4v
+title: Editor
+description: "Content entry editor components and hooks"
+---
+
+import { Alert } from "@/components/Alert";
+import { SymbolList } from "@/components/SymbolList";
+
+
+
+- What is exported from `webiny/admin/cms/entry/editor`?
+- How to import and use each exported item?
+
+
+
+## Overview
+
+This page documents everything exported from `webiny/admin/cms/entry/editor`. Import any of the items below directly from this path in your Webiny extensions.
+
+**Components**
+
+
+
+**Hooks**
+
+
+
+## Components
+
+### `ContentEntryEditorConfig`
+
+**Constant** — imported from `webiny/admin/cms/entry/editor`
+
+```typescript
+import { ContentEntryEditorConfig } from "webiny/admin/cms/entry/editor";
+```
+
+```typescript
+export const ContentEntryEditorConfig = Object.assign(base.Config, {
+ Actions,
+ FieldElement,
+ Width,
+ ValidationIndicators: ValidationIndicatorsConfig
+});
+```
+
+## Hooks
+
+### `useContentEntryEditor`
+
+**Constant** — imported from `webiny/admin/cms/entry/editor`
+
+```typescript
+import { useContentEntryEditor } from "webiny/admin/cms/entry/editor";
+```
+
+```typescript
+export const useContentEntry = makeDecoratable(() => {
+ const context = useContext(ContentEntryContext);
+ if (!context) {
+ throw Error(`useContentEntry() hook can only be used within the ContentEntryContext provider.`);
+ }
+ return context;
+});
+```
+
+### `useContentEntryForm`
+
+**Constant** — imported from `webiny/admin/cms/entry/editor`
+
+```typescript
+import { useContentEntryForm } from "webiny/admin/cms/entry/editor";
+```
+
+```typescript
+export const useContentEntryForm = makeDecoratable(() => {
+ const context = React.useContext(ContentEntryFormContext);
+ if (!context) {
+ throw new Error("ContentEntryFormProvider is missing in the component hierarchy!");
+ }
+
+ return context;
+});
+```
+
+### `useSingleEntryContentEntry`
+
+**Constant** — imported from `webiny/admin/cms/entry/editor`
+
+```typescript
+import { useSingleEntryContentEntry } from "webiny/admin/cms/entry/editor";
+```
+
+```typescript
+export const useSingletonContentEntry = makeDecoratable(() => {
+ const context = useContext(SingletonContentEntryContext);
+ if (!context) {
+ throw Error(
+ `useSingletonContentEntry() hook can only be used within the SingletonContentEntryContext provider.`
+ );
+ }
+ return context;
+});
+```
diff --git a/docs/developer-docs/6.0.x/reference/admin/cms/entry/list.ai.txt b/docs/developer-docs/6.0.x/reference/admin/cms/entry/list.ai.txt
new file mode 100644
index 000000000..7c80a8db2
--- /dev/null
+++ b/docs/developer-docs/6.0.x/reference/admin/cms/entry/list.ai.txt
@@ -0,0 +1,26 @@
+AI Context: List (reference/admin/cms/entry/list.mdx)
+
+Source of Information:
+1. packages/webiny/src/admin/cms/entry/list.ts — barrel re-export file
+2. /Users/adrian/dev/wby-next/packages/app-headless-cms/src/admin/config/contentEntries/index.ts — originating source
+3. /Users/adrian/dev/wby-next/packages/app-headless-cms/src/admin/hooks/index.ts — originating source
+
+Key Documentation Decisions:
+- This file is auto-generated by scripts/generate-reference.ts — do not edit manually
+- Symbols are documented in the order they appear in the barrel file
+- Declaration text is extracted from the TypeScript AST; method bodies are stripped
+- Type-only exports are labeled as "Type"; namespace exports include member listings
+
+Exported Symbols:
+ContentEntryListConfig, useContentEntriesList
+
+Import Path: webiny/admin/cms/entry/list
+
+Related Documents:
+- docs/developer-docs/6.0.x/basic/di.mdx — DI pattern used by all abstractions
+- docs/developer-docs/6.0.x/basic/result.mdx — Result type used in use case returns
+
+Tone Guidelines:
+- This is a reference page — terse, API-focused, no prose beyond what's necessary
+- Code blocks are the primary content; descriptions serve only to clarify intent
+- Do not add analogies or long explanations — link to guide pages for those
diff --git a/docs/developer-docs/6.0.x/reference/admin/cms/entry/list.mdx b/docs/developer-docs/6.0.x/reference/admin/cms/entry/list.mdx
new file mode 100644
index 000000000..4fc1e69f3
--- /dev/null
+++ b/docs/developer-docs/6.0.x/reference/admin/cms/entry/list.mdx
@@ -0,0 +1,51 @@
+---
+id: ywrtaw4v
+title: List
+description: "Content entry list configuration"
+---
+
+import { Alert } from "@/components/Alert";
+import { SymbolList } from "@/components/SymbolList";
+
+
+
+- What is exported from `webiny/admin/cms/entry/list`?
+- How to import and use each exported item?
+
+
+
+## Overview
+
+This page documents everything exported from `webiny/admin/cms/entry/list`. Import any of the items below directly from this path in your Webiny extensions.
+
+**Components**
+
+
+
+**Other**
+
+
+
+## Components
+
+### `ContentEntryListConfig`
+
+**Constant** — imported from `webiny/admin/cms/entry/list`
+
+```typescript
+import { ContentEntryListConfig } from "webiny/admin/cms/entry/list";
+```
+
+```typescript
+export const ContentEntryListConfig = Object.assign(PublicContentEntryListConfig, { Browser });
+```
+
+## Other
+
+### `useContentEntriesList`
+
+**Export** — imported from `webiny/admin/cms/entry/list`
+
+```typescript
+import { useContentEntriesList } from "webiny/admin/cms/entry/list";
+```
diff --git a/docs/developer-docs/6.0.x/reference/admin/cms/fieldRenderers/dynamic-zone.ai.txt b/docs/developer-docs/6.0.x/reference/admin/cms/fieldRenderers/dynamic-zone.ai.txt
new file mode 100644
index 000000000..ef5bdb06c
--- /dev/null
+++ b/docs/developer-docs/6.0.x/reference/admin/cms/fieldRenderers/dynamic-zone.ai.txt
@@ -0,0 +1,25 @@
+AI Context: Dynamic Zone (reference/admin/cms/fieldRenderers/dynamic-zone.mdx)
+
+Source of Information:
+1. packages/webiny/src/admin/cms/fieldRenderers/dynamic-zone.ts — barrel re-export file
+
+
+Key Documentation Decisions:
+- This file is auto-generated by scripts/generate-reference.ts — do not edit manually
+- Symbols are documented in the order they appear in the barrel file
+- Declaration text is extracted from the TypeScript AST; method bodies are stripped
+- Type-only exports are labeled as "Type"; namespace exports include member listings
+
+Exported Symbols:
+
+
+Import Path: webiny/admin/cms/fieldRenderers/dynamic-zone
+
+Related Documents:
+- docs/developer-docs/6.0.x/basic/di.mdx — DI pattern used by all abstractions
+- docs/developer-docs/6.0.x/basic/result.mdx — Result type used in use case returns
+
+Tone Guidelines:
+- This is a reference page — terse, API-focused, no prose beyond what's necessary
+- Code blocks are the primary content; descriptions serve only to clarify intent
+- Do not add analogies or long explanations — link to guide pages for those
diff --git a/docs/developer-docs/6.0.x/reference/admin/cms/fieldRenderers/dynamic-zone.mdx b/docs/developer-docs/6.0.x/reference/admin/cms/fieldRenderers/dynamic-zone.mdx
new file mode 100644
index 000000000..d0715ac77
--- /dev/null
+++ b/docs/developer-docs/6.0.x/reference/admin/cms/fieldRenderers/dynamic-zone.mdx
@@ -0,0 +1,21 @@
+---
+id: ywrtaw4v
+title: Dynamic Zone
+description: "Reference for webiny/admin/cms/fieldRenderers/dynamic-zone"
+---
+
+import { Alert } from "@/components/Alert";
+import { SymbolList } from "@/components/SymbolList";
+
+
+
+- What is exported from `webiny/admin/cms/fieldRenderers/dynamic-zone`?
+- How to import and use each exported item?
+
+
+
+## Overview
+
+This page documents everything exported from `webiny/admin/cms/fieldRenderers/dynamic-zone`. Import any of the items below directly from this path in your Webiny extensions.
+
+_No exported symbols found._
diff --git a/docs/developer-docs/6.0.x/reference/admin/cms/fieldRenderers/dynamicZone.ai.txt b/docs/developer-docs/6.0.x/reference/admin/cms/fieldRenderers/dynamicZone.ai.txt
new file mode 100644
index 000000000..bcd8aad34
--- /dev/null
+++ b/docs/developer-docs/6.0.x/reference/admin/cms/fieldRenderers/dynamicZone.ai.txt
@@ -0,0 +1,25 @@
+AI Context: DynamicZone (reference/admin/cms/fieldRenderers/dynamicZone.mdx)
+
+Source of Information:
+1. packages/webiny/src/admin/cms/fieldRenderers/dynamicZone.ts — barrel re-export file
+
+
+Key Documentation Decisions:
+- This file is auto-generated by scripts/generate-reference.ts — do not edit manually
+- Symbols are documented in the order they appear in the barrel file
+- Declaration text is extracted from the TypeScript AST; method bodies are stripped
+- Type-only exports are labeled as "Type"; namespace exports include member listings
+
+Exported Symbols:
+
+
+Import Path: webiny/admin/cms/fieldRenderers/dynamicZone
+
+Related Documents:
+- docs/developer-docs/6.0.x/basic/di.mdx — DI pattern used by all abstractions
+- docs/developer-docs/6.0.x/basic/result.mdx — Result type used in use case returns
+
+Tone Guidelines:
+- This is a reference page — terse, API-focused, no prose beyond what's necessary
+- Code blocks are the primary content; descriptions serve only to clarify intent
+- Do not add analogies or long explanations — link to guide pages for those
diff --git a/docs/developer-docs/6.0.x/reference/admin/cms/fieldRenderers/dynamicZone.mdx b/docs/developer-docs/6.0.x/reference/admin/cms/fieldRenderers/dynamicZone.mdx
new file mode 100644
index 000000000..348784ce4
--- /dev/null
+++ b/docs/developer-docs/6.0.x/reference/admin/cms/fieldRenderers/dynamicZone.mdx
@@ -0,0 +1,21 @@
+---
+id: ywrtaw4v
+title: DynamicZone
+description: "Dynamic zone field renderer components"
+---
+
+import { Alert } from "@/components/Alert";
+import { SymbolList } from "@/components/SymbolList";
+
+
+
+- What is exported from `webiny/admin/cms/fieldRenderers/dynamicZone`?
+- How to import and use each exported item?
+
+
+
+## Overview
+
+This page documents everything exported from `webiny/admin/cms/fieldRenderers/dynamicZone`. Import any of the items below directly from this path in your Webiny extensions.
+
+_No exported symbols found._
diff --git a/docs/developer-docs/6.0.x/reference/admin/cms/fieldRenderers/object.ai.txt b/docs/developer-docs/6.0.x/reference/admin/cms/fieldRenderers/object.ai.txt
new file mode 100644
index 000000000..fcd502b81
--- /dev/null
+++ b/docs/developer-docs/6.0.x/reference/admin/cms/fieldRenderers/object.ai.txt
@@ -0,0 +1,25 @@
+AI Context: Object (reference/admin/cms/fieldRenderers/object.mdx)
+
+Source of Information:
+1. packages/webiny/src/admin/cms/fieldRenderers/object.ts — barrel re-export file
+
+
+Key Documentation Decisions:
+- This file is auto-generated by scripts/generate-reference.ts — do not edit manually
+- Symbols are documented in the order they appear in the barrel file
+- Declaration text is extracted from the TypeScript AST; method bodies are stripped
+- Type-only exports are labeled as "Type"; namespace exports include member listings
+
+Exported Symbols:
+
+
+Import Path: webiny/admin/cms/fieldRenderers/object
+
+Related Documents:
+- docs/developer-docs/6.0.x/basic/di.mdx — DI pattern used by all abstractions
+- docs/developer-docs/6.0.x/basic/result.mdx — Result type used in use case returns
+
+Tone Guidelines:
+- This is a reference page — terse, API-focused, no prose beyond what's necessary
+- Code blocks are the primary content; descriptions serve only to clarify intent
+- Do not add analogies or long explanations — link to guide pages for those
diff --git a/docs/developer-docs/6.0.x/reference/admin/cms/fieldRenderers/object.mdx b/docs/developer-docs/6.0.x/reference/admin/cms/fieldRenderers/object.mdx
new file mode 100644
index 000000000..37925bb50
--- /dev/null
+++ b/docs/developer-docs/6.0.x/reference/admin/cms/fieldRenderers/object.mdx
@@ -0,0 +1,21 @@
+---
+id: ywrtaw4v
+title: Object
+description: "Object field renderer components"
+---
+
+import { Alert } from "@/components/Alert";
+import { SymbolList } from "@/components/SymbolList";
+
+
+
+- What is exported from `webiny/admin/cms/fieldRenderers/object`?
+- How to import and use each exported item?
+
+
+
+## Overview
+
+This page documents everything exported from `webiny/admin/cms/fieldRenderers/object`. Import any of the items below directly from this path in your Webiny extensions.
+
+_No exported symbols found._
diff --git a/docs/developer-docs/6.0.x/reference/admin/cms/lexical.ai.txt b/docs/developer-docs/6.0.x/reference/admin/cms/lexical.ai.txt
new file mode 100644
index 000000000..46e31057e
--- /dev/null
+++ b/docs/developer-docs/6.0.x/reference/admin/cms/lexical.ai.txt
@@ -0,0 +1,25 @@
+AI Context: Lexical Editor (reference/admin/cms/lexical.mdx)
+
+Source of Information:
+1. packages/webiny/src/admin/cms/lexical.ts — barrel re-export file
+2. /Users/adrian/dev/wby-next/packages/lexical-editor/src/exports/admin/lexical.ts — originating source
+
+Key Documentation Decisions:
+- This file is auto-generated by scripts/generate-reference.ts — do not edit manually
+- Symbols are documented in the order they appear in the barrel file
+- Declaration text is extracted from the TypeScript AST; method bodies are stripped
+- Type-only exports are labeled as "Type"; namespace exports include member listings
+
+Exported Symbols:
+useLexicalEditorConfig, LexicalHtmlRenderer, getNodeFromSelection, useCurrentElement, useCurrentSelection, useDeriveValueFromSelection, useRichTextEditor, useFontColorPicker, useTextAlignmentAction, useTypographyAction, useIsMounted, Divider, DropDownItem, DropDown, Klass, LexicalNode
+
+Import Path: webiny/admin/cms/lexical
+
+Related Documents:
+- docs/developer-docs/6.0.x/basic/di.mdx — DI pattern used by all abstractions
+- docs/developer-docs/6.0.x/basic/result.mdx — Result type used in use case returns
+
+Tone Guidelines:
+- This is a reference page — terse, API-focused, no prose beyond what's necessary
+- Code blocks are the primary content; descriptions serve only to clarify intent
+- Do not add analogies or long explanations — link to guide pages for those
diff --git a/docs/developer-docs/6.0.x/reference/admin/cms/lexical.mdx b/docs/developer-docs/6.0.x/reference/admin/cms/lexical.mdx
new file mode 100644
index 000000000..38113ff49
--- /dev/null
+++ b/docs/developer-docs/6.0.x/reference/admin/cms/lexical.mdx
@@ -0,0 +1,168 @@
+---
+id: ywrtaw4v
+title: Lexical Editor
+description: "CMS Lexical rich-text editor config"
+---
+
+import { Alert } from "@/components/Alert";
+import { SymbolList } from "@/components/SymbolList";
+
+
+
+- What is exported from `webiny/admin/cms/lexical`?
+- How to import and use each exported item?
+
+
+
+## Overview
+
+This page documents everything exported from `webiny/admin/cms/lexical`. Import any of the items below directly from this path in your Webiny extensions.
+
+
+
+## `Divider`
+
+**Export** — imported from `webiny/admin/cms/lexical`
+
+```typescript
+import { Divider } from "webiny/admin/cms/lexical";
+```
+
+## `DropDown`
+
+**Export** — imported from `webiny/admin/cms/lexical`
+
+```typescript
+import { DropDown } from "webiny/admin/cms/lexical";
+```
+
+## `DropDownItem`
+
+**Export** — imported from `webiny/admin/cms/lexical`
+
+```typescript
+import { DropDownItem } from "webiny/admin/cms/lexical";
+```
+
+## `getNodeFromSelection`
+
+**Export** — imported from `webiny/admin/cms/lexical`
+
+```typescript
+import { getNodeFromSelection } from "webiny/admin/cms/lexical";
+```
+
+## `Klass`
+
+**Type** — imported from `webiny/admin/cms/lexical`
+
+```typescript
+import type { Klass } from "webiny/admin/cms/lexical";
+```
+
+## `LexicalHtmlRenderer`
+
+**Export** — imported from `webiny/admin/cms/lexical`
+
+```typescript
+import { LexicalHtmlRenderer } from "webiny/admin/cms/lexical";
+```
+
+## `LexicalNode`
+
+**Type** — imported from `webiny/admin/cms/lexical`
+
+```typescript
+import type { LexicalNode } from "webiny/admin/cms/lexical";
+```
+
+## `useCurrentElement`
+
+**Export** — imported from `webiny/admin/cms/lexical`
+
+```typescript
+import { useCurrentElement } from "webiny/admin/cms/lexical";
+```
+
+## `useCurrentSelection`
+
+**Export** — imported from `webiny/admin/cms/lexical`
+
+```typescript
+import { useCurrentSelection } from "webiny/admin/cms/lexical";
+```
+
+## `useDeriveValueFromSelection`
+
+**Export** — imported from `webiny/admin/cms/lexical`
+
+```typescript
+import { useDeriveValueFromSelection } from "webiny/admin/cms/lexical";
+```
+
+## `useFontColorPicker`
+
+**Export** — imported from `webiny/admin/cms/lexical`
+
+```typescript
+import { useFontColorPicker } from "webiny/admin/cms/lexical";
+```
+
+## `useIsMounted`
+
+**Export** — imported from `webiny/admin/cms/lexical`
+
+```typescript
+import { useIsMounted } from "webiny/admin/cms/lexical";
+```
+
+## `useLexicalEditorConfig`
+
+**Export** — imported from `webiny/admin/cms/lexical`
+
+```typescript
+import { useLexicalEditorConfig } from "webiny/admin/cms/lexical";
+```
+
+## `useRichTextEditor`
+
+**Export** — imported from `webiny/admin/cms/lexical`
+
+```typescript
+import { useRichTextEditor } from "webiny/admin/cms/lexical";
+```
+
+## `useTextAlignmentAction`
+
+**Export** — imported from `webiny/admin/cms/lexical`
+
+```typescript
+import { useTextAlignmentAction } from "webiny/admin/cms/lexical";
+```
+
+## `useTypographyAction`
+
+**Export** — imported from `webiny/admin/cms/lexical`
+
+```typescript
+import { useTypographyAction } from "webiny/admin/cms/lexical";
+```
diff --git a/docs/developer-docs/6.0.x/reference/admin/cms/model.ai.txt b/docs/developer-docs/6.0.x/reference/admin/cms/model.ai.txt
new file mode 100644
index 000000000..eedddd27a
--- /dev/null
+++ b/docs/developer-docs/6.0.x/reference/admin/cms/model.ai.txt
@@ -0,0 +1,26 @@
+AI Context: Model (reference/admin/cms/model.mdx)
+
+Source of Information:
+1. packages/webiny/src/admin/cms/model.ts — barrel re-export file
+2. /Users/adrian/dev/wby-next/packages/app-headless-cms-common/src/Fields/index.ts — originating source
+3. /Users/adrian/dev/wby-next/packages/app-headless-cms-common/src/types/index.ts — originating source
+
+Key Documentation Decisions:
+- This file is auto-generated by scripts/generate-reference.ts — do not edit manually
+- Symbols are documented in the order they appear in the barrel file
+- Declaration text is extracted from the TypeScript AST; method bodies are stripped
+- Type-only exports are labeled as "Type"; namespace exports include member listings
+
+Exported Symbols:
+useFieldAccessControlRules, useEffectiveRules, CmsLayoutFieldTypePlugin, CmsLayoutDescriptorRendererPlugin, CmsBaseLayoutDescriptor, CmsLayoutDescriptor
+
+Import Path: webiny/admin/cms/model
+
+Related Documents:
+- docs/developer-docs/6.0.x/basic/di.mdx — DI pattern used by all abstractions
+- docs/developer-docs/6.0.x/basic/result.mdx — Result type used in use case returns
+
+Tone Guidelines:
+- This is a reference page — terse, API-focused, no prose beyond what's necessary
+- Code blocks are the primary content; descriptions serve only to clarify intent
+- Do not add analogies or long explanations — link to guide pages for those
diff --git a/docs/developer-docs/6.0.x/reference/admin/cms/model.mdx b/docs/developer-docs/6.0.x/reference/admin/cms/model.mdx
new file mode 100644
index 000000000..4be25704a
--- /dev/null
+++ b/docs/developer-docs/6.0.x/reference/admin/cms/model.mdx
@@ -0,0 +1,131 @@
+---
+id: ywrtaw4v
+title: Model
+description: "Reference for webiny/admin/cms/model"
+---
+
+import { Alert } from "@/components/Alert";
+import { SymbolList } from "@/components/SymbolList";
+
+
+
+- What is exported from `webiny/admin/cms/model`?
+- How to import and use each exported item?
+
+
+
+## Overview
+
+This page documents everything exported from `webiny/admin/cms/model`. Import any of the items below directly from this path in your Webiny extensions.
+
+**Hooks**
+
+
+
+**Types**
+
+
+
+## Hooks
+
+### `useEffectiveRules`
+
+**Function** — imported from `webiny/admin/cms/model`
+
+Composes useParentRules and useFieldRules into a single hook
+that returns the effective (intersected) rules.
+
+```typescript
+import { useEffectiveRules } from "webiny/admin/cms/model";
+```
+
+```typescript
+export function useEffectiveRules(item: HasRules): EffectiveFieldRules;
+```
+
+### `useFieldAccessControlRules`
+
+**Function** — imported from `webiny/admin/cms/model`
+
+Hook that evaluates access control rules for the current identity.
+Does not require `bindParentName` — only identity-based permissions.
+
+```typescript
+import { useFieldAccessControlRules } from "webiny/admin/cms/model";
+```
+
+```typescript
+export function useFieldAccessControlRules(
+ item: HasRules
+): Pick;
+```
+
+## Types
+
+### `CmsBaseLayoutDescriptor`
+
+**Type** — imported from `webiny/admin/cms/model`
+
+```typescript
+import type { CmsBaseLayoutDescriptor } from "webiny/admin/cms/model";
+```
+
+```typescript
+export interface CmsBaseLayoutDescriptor {
+ id: string;
+ type: string;
+ rules?: FieldRule[];
+}
+```
+
+### `CmsLayoutDescriptor`
+
+**Type** — imported from `webiny/admin/cms/model`
+
+```typescript
+import type { CmsLayoutDescriptor } from "webiny/admin/cms/model";
+```
+
+```typescript
+export type CmsLayoutDescriptor =
+ | CmsSeparatorLayoutDescriptor
+ | CmsAlertLayoutDescriptor
+ | CmsTabLayoutDescriptor
+ | CmsBaseLayoutDescriptor;
+```
+
+### `CmsLayoutDescriptorRendererPlugin`
+
+**Type** — imported from `webiny/admin/cms/model`
+
+```typescript
+import type { CmsLayoutDescriptorRendererPlugin } from "webiny/admin/cms/model";
+```
+
+```typescript
+export interface CmsLayoutDescriptorRendererPlugin extends Plugin { ... }
+```
+
+### `CmsLayoutFieldTypePlugin`
+
+**Type** — imported from `webiny/admin/cms/model`
+
+```typescript
+import type { CmsLayoutFieldTypePlugin } from "webiny/admin/cms/model";
+```
+
+```typescript
+export interface CmsLayoutFieldTypePlugin extends Plugin { ... }
+```
diff --git a/docs/developer-docs/6.0.x/reference/admin/configs.ai.txt b/docs/developer-docs/6.0.x/reference/admin/configs.ai.txt
new file mode 100644
index 000000000..d07f212ad
--- /dev/null
+++ b/docs/developer-docs/6.0.x/reference/admin/configs.ai.txt
@@ -0,0 +1,25 @@
+AI Context: Configs (reference/admin/configs.mdx)
+
+Source of Information:
+1. packages/webiny/src/admin/configs.ts — barrel re-export file
+
+
+Key Documentation Decisions:
+- This file is auto-generated by scripts/generate-reference.ts — do not edit manually
+- Symbols are documented in the order they appear in the barrel file
+- Declaration text is extracted from the TypeScript AST; method bodies are stripped
+- Type-only exports are labeled as "Type"; namespace exports include member listings
+
+Exported Symbols:
+
+
+Import Path: webiny/admin/configs
+
+Related Documents:
+- docs/developer-docs/6.0.x/basic/di.mdx — DI pattern used by all abstractions
+- docs/developer-docs/6.0.x/basic/result.mdx — Result type used in use case returns
+
+Tone Guidelines:
+- This is a reference page — terse, API-focused, no prose beyond what's necessary
+- Code blocks are the primary content; descriptions serve only to clarify intent
+- Do not add analogies or long explanations — link to guide pages for those
diff --git a/docs/developer-docs/6.0.x/reference/admin/configs.mdx b/docs/developer-docs/6.0.x/reference/admin/configs.mdx
new file mode 100644
index 000000000..4f863d758
--- /dev/null
+++ b/docs/developer-docs/6.0.x/reference/admin/configs.mdx
@@ -0,0 +1,21 @@
+---
+id: ywrtaw4v
+title: Configs
+description: "Admin configuration types"
+---
+
+import { Alert } from "@/components/Alert";
+import { SymbolList } from "@/components/SymbolList";
+
+
+
+- What is exported from `webiny/admin/configs`?
+- How to import and use each exported item?
+
+
+
+## Overview
+
+This page documents everything exported from `webiny/admin/configs`. Import any of the items below directly from this path in your Webiny extensions.
+
+_No exported symbols found._
diff --git a/docs/developer-docs/6.0.x/reference/admin/env-config.ai.txt b/docs/developer-docs/6.0.x/reference/admin/env-config.ai.txt
new file mode 100644
index 000000000..f06611619
--- /dev/null
+++ b/docs/developer-docs/6.0.x/reference/admin/env-config.ai.txt
@@ -0,0 +1,25 @@
+AI Context: Env Config (reference/admin/env-config.mdx)
+
+Source of Information:
+1. packages/webiny/src/admin/env-config.ts — barrel re-export file
+2. /Users/adrian/dev/wby-next/packages/app/src/features/envConfig/index.ts — originating source
+
+Key Documentation Decisions:
+- This file is auto-generated by scripts/generate-reference.ts — do not edit manually
+- Symbols are documented in the order they appear in the barrel file
+- Declaration text is extracted from the TypeScript AST; method bodies are stripped
+- Type-only exports are labeled as "Type"; namespace exports include member listings
+
+Exported Symbols:
+EnvConfig
+
+Import Path: webiny/admin/env-config
+
+Related Documents:
+- docs/developer-docs/6.0.x/basic/di.mdx — DI pattern used by all abstractions
+- docs/developer-docs/6.0.x/basic/result.mdx — Result type used in use case returns
+
+Tone Guidelines:
+- This is a reference page — terse, API-focused, no prose beyond what's necessary
+- Code blocks are the primary content; descriptions serve only to clarify intent
+- Do not add analogies or long explanations — link to guide pages for those
diff --git a/docs/developer-docs/6.0.x/reference/admin/env-config.mdx b/docs/developer-docs/6.0.x/reference/admin/env-config.mdx
new file mode 100644
index 000000000..62088ff73
--- /dev/null
+++ b/docs/developer-docs/6.0.x/reference/admin/env-config.mdx
@@ -0,0 +1,33 @@
+---
+id: ywrtaw4v
+title: Env Config
+description: "Reference for webiny/admin/env-config"
+---
+
+import { Alert } from "@/components/Alert";
+import { SymbolList } from "@/components/SymbolList";
+
+
+
+- What is exported from `webiny/admin/env-config`?
+- How to import and use each exported item?
+
+
+
+## Overview
+
+This page documents everything exported from `webiny/admin/env-config`. Import any of the items below directly from this path in your Webiny extensions.
+
+
+
+## `EnvConfig`
+
+**Constant** — imported from `webiny/admin/env-config`
+
+```typescript
+import { EnvConfig } from "webiny/admin/env-config";
+```
+
+```typescript
+export const EnvConfig = new Abstraction("EnvConfig");
+```
diff --git a/docs/developer-docs/6.0.x/reference/admin/envConfig.ai.txt b/docs/developer-docs/6.0.x/reference/admin/envConfig.ai.txt
new file mode 100644
index 000000000..bdcd7a895
--- /dev/null
+++ b/docs/developer-docs/6.0.x/reference/admin/envConfig.ai.txt
@@ -0,0 +1,25 @@
+AI Context: Env Config (reference/admin/envConfig.mdx)
+
+Source of Information:
+1. packages/webiny/src/admin/envConfig.ts — barrel re-export file
+2. /Users/adrian/dev/wby-next/packages/app/src/features/envConfig/index.ts — originating source
+
+Key Documentation Decisions:
+- This file is auto-generated by scripts/generate-reference.ts — do not edit manually
+- Symbols are documented in the order they appear in the barrel file
+- Declaration text is extracted from the TypeScript AST; method bodies are stripped
+- Type-only exports are labeled as "Type"; namespace exports include member listings
+
+Exported Symbols:
+EnvConfig
+
+Import Path: webiny/admin/envConfig
+
+Related Documents:
+- docs/developer-docs/6.0.x/basic/di.mdx — DI pattern used by all abstractions
+- docs/developer-docs/6.0.x/basic/result.mdx — Result type used in use case returns
+
+Tone Guidelines:
+- This is a reference page — terse, API-focused, no prose beyond what's necessary
+- Code blocks are the primary content; descriptions serve only to clarify intent
+- Do not add analogies or long explanations — link to guide pages for those
diff --git a/docs/developer-docs/6.0.x/reference/admin/envConfig.mdx b/docs/developer-docs/6.0.x/reference/admin/envConfig.mdx
new file mode 100644
index 000000000..4615fe11f
--- /dev/null
+++ b/docs/developer-docs/6.0.x/reference/admin/envConfig.mdx
@@ -0,0 +1,33 @@
+---
+id: ywrtaw4v
+title: Env Config
+description: "Environment configuration for admin"
+---
+
+import { Alert } from "@/components/Alert";
+import { SymbolList } from "@/components/SymbolList";
+
+
+
+- What is exported from `webiny/admin/envConfig`?
+- How to import and use each exported item?
+
+
+
+## Overview
+
+This page documents everything exported from `webiny/admin/envConfig`. Import any of the items below directly from this path in your Webiny extensions.
+
+
+
+## `EnvConfig`
+
+**Constant** — imported from `webiny/admin/envConfig`
+
+```typescript
+import { EnvConfig } from "webiny/admin/envConfig";
+```
+
+```typescript
+export const EnvConfig = new Abstraction("EnvConfig");
+```
diff --git a/docs/developer-docs/6.0.x/reference/admin/form.ai.txt b/docs/developer-docs/6.0.x/reference/admin/form.ai.txt
new file mode 100644
index 000000000..132963c10
--- /dev/null
+++ b/docs/developer-docs/6.0.x/reference/admin/form.ai.txt
@@ -0,0 +1,26 @@
+AI Context: Form (reference/admin/form.mdx)
+
+Source of Information:
+1. packages/webiny/src/admin/form.ts — barrel re-export file
+2. /Users/adrian/dev/wby-next/packages/form/src/index.ts — originating source
+3. /Users/adrian/dev/wby-next/packages/validation/src/index.ts — originating source
+
+Key Documentation Decisions:
+- This file is auto-generated by scripts/generate-reference.ts — do not edit manually
+- Symbols are documented in the order they appear in the barrel file
+- Declaration text is extracted from the TypeScript AST; method bodies are stripped
+- Type-only exports are labeled as "Type"; namespace exports include member listings
+
+Exported Symbols:
+Bind, Form, UnsetOnUnmount, useBind, useBindPrefix, useGenerateSlug, useForm, FormApi, FormOnSubmit, GenericFormData, validation, Validation, ValidationError
+
+Import Path: webiny/admin/form
+
+Related Documents:
+- docs/developer-docs/6.0.x/basic/di.mdx — DI pattern used by all abstractions
+- docs/developer-docs/6.0.x/basic/result.mdx — Result type used in use case returns
+
+Tone Guidelines:
+- This is a reference page — terse, API-focused, no prose beyond what's necessary
+- Code blocks are the primary content; descriptions serve only to clarify intent
+- Do not add analogies or long explanations — link to guide pages for those
diff --git a/docs/developer-docs/6.0.x/reference/admin/form.mdx b/docs/developer-docs/6.0.x/reference/admin/form.mdx
new file mode 100644
index 000000000..11160ea49
--- /dev/null
+++ b/docs/developer-docs/6.0.x/reference/admin/form.mdx
@@ -0,0 +1,296 @@
+---
+id: ywrtaw4v
+title: Form
+description: "Form primitives: Bind, Form, useForm, validation"
+---
+
+import { Alert } from "@/components/Alert";
+import { SymbolList } from "@/components/SymbolList";
+
+
+
+- What is exported from `webiny/admin/form`?
+- How to import and use each exported item?
+
+
+
+## Overview
+
+This page documents everything exported from `webiny/admin/form`. Import any of the items below directly from this path in your Webiny extensions.
+
+**Components**
+
+
+
+**Hooks**
+
+
+
+**Types**
+
+
+
+**Other**
+
+
+
+## Components
+
+### `Bind`
+
+**Function** — imported from `webiny/admin/form`
+
+```typescript
+import { Bind } from "webiny/admin/form";
+```
+
+```typescript
+export function Bind(
+```
+
+### `Form`
+
+**Constant** — imported from `webiny/admin/form`
+
+```typescript
+import { Form } from "webiny/admin/form";
+```
+
+```typescript
+export const Form = observer(
+ React.forwardRef(FormInner) as (
+ props: FormProps & { ref?: React.ForwardedRef }
+ ) => ReturnType>
+);
+```
+
+### `UnsetOnUnmount`
+
+**Constant** — imported from `webiny/admin/form`
+
+```typescript
+import { UnsetOnUnmount } from "webiny/admin/form";
+```
+
+```typescript
+export const UnsetOnUnmount = ({ name, children }: { name: string; children: React.ReactNode }) => {
+ const form = useForm();
+
+ useEffect(() => {
+ return () => {
+ form.setValue(name, undefined);
+ };
+ }, []);
+
+ return <>{children}>;
+};
+```
+
+### `Validation`
+
+**Class** — imported from `webiny/admin/form`
+
+Main class of Validation library.
+Exported as a singleton instance, it offers methods for sync/async data validation and overwriting or adding new validators.
+
+@class Validation
+@example
+import { validation } from '@webiny/validation';
+
+// `validation` is a preconfigured instance of Validation class.
+// From here you can either add new validators or use it as-is.
+
+```typescript
+import { Validation } from "webiny/admin/form";
+```
+
+```typescript
+class Validation {
+ __validators:;
+ constructor();
+ setValidator(name: string, callable: Validator): this;
+ getValidator(name: string): Validator;
+ async validate(
+ value: any,
+ validators: string,
+ options: ValidateOptions =;
+ validateSync(
+ value: any,
+ validators: string,
+ options: ValidateOptions =;
+ create(validators: string);
+ createSync(validators: string);
+ __parseValidateProperty(validators: string): ParsedValidators;
+}
+```
+
+### `ValidationError`
+
+**Class** — imported from `webiny/admin/form`
+
+This class is used by validators to throw an error when value validation fails.
+
+```typescript
+import { ValidationError } from "webiny/admin/form";
+```
+
+```typescript
+class ValidationError extends Error {
+ public override readonly message: string;
+ public readonly validator: string | null;
+ public readonly value: any;
+ constructor(message = "", validator: string | null = null, value: string | null = null);
+}
+```
+
+## Hooks
+
+### `useBind`
+
+**Constant** — imported from `webiny/admin/form`
+
+```typescript
+import { useBind } from "webiny/admin/form";
+```
+
+```typescript
+export const useBind = makeDecoratable((props: BindComponentProps): UseBindHook => {
+ const form = useForm();
+ const bindPrefix = useBindPrefix();
+
+ const bindName = useMemo(() => {
+ return [bindPrefix, props.name].filter(Boolean).join(".");
+ }, [props.name]);
+
+ const fieldProps = { ...props, name: bindName };
+
+ useEffect(() => {
+ form.registerField(fieldProps);
+
+
+```
+
+### `useBindPrefix`
+
+**Function** — imported from `webiny/admin/form`
+
+```typescript
+import { useBindPrefix } from "webiny/admin/form";
+```
+
+```typescript
+export function useBindPrefix();
+```
+
+### `useForm`
+
+**Constant** — imported from `webiny/admin/form`
+
+```typescript
+import { useForm } from "webiny/admin/form";
+```
+
+```typescript
+export const useForm = () => {
+ const context = useContext(FormContext) as FormAPI;
+ if (!context) {
+ throw new Error("Missing Form component in the component hierarchy!");
+ }
+ return context;
+};
+```
+
+### `useGenerateSlug`
+
+**Function** — imported from `webiny/admin/form`
+
+This hook is designed to be used with the `useForm` hook.
+When `generateSlug` is called, it will generate a slug using the `from` form field, and set it into the `to` form field.
+@param form
+@param from
+@param to
+
+```typescript
+import { useGenerateSlug } from "webiny/admin/form";
+```
+
+```typescript
+export function useGenerateSlug(form: FormAPI, from: string, to = "slug");
+```
+
+## Types
+
+### `FormApi`
+
+**Type** — imported from `webiny/admin/form`
+
+```typescript
+import type { FormApi } from "webiny/admin/form";
+```
+
+```typescript
+export interface FormAPI { ... }
+```
+
+### `FormOnSubmit`
+
+**Type** — imported from `webiny/admin/form`
+
+```typescript
+import type { FormOnSubmit } from "webiny/admin/form";
+```
+
+```typescript
+export interface FormOnSubmit {
+ (data: T, form: FormAPI): any;
+}
+```
+
+### `GenericFormData`
+
+**Type** — imported from `webiny/admin/form`
+
+```typescript
+import type { GenericFormData } from "webiny/admin/form";
+```
+
+```typescript
+export type GenericFormData = {
+ [key: string]: any;
+};
+```
+
+## Other
+
+### `validation`
+
+**Constant** — imported from `webiny/admin/form`
+
+```typescript
+import { validation } from "webiny/admin/form";
+```
+
+```typescript
+export const validation = new Validation();
+```
diff --git a/docs/developer-docs/6.0.x/reference/admin/graphql-client.ai.txt b/docs/developer-docs/6.0.x/reference/admin/graphql-client.ai.txt
new file mode 100644
index 000000000..9767dd619
--- /dev/null
+++ b/docs/developer-docs/6.0.x/reference/admin/graphql-client.ai.txt
@@ -0,0 +1,25 @@
+AI Context: Graphql Client (reference/admin/graphql-client.mdx)
+
+Source of Information:
+1. packages/webiny/src/admin/graphql-client.ts — barrel re-export file
+2. /Users/adrian/dev/wby-next/packages/app/src/features/graphqlClient/abstractions.ts — originating source
+
+Key Documentation Decisions:
+- This file is auto-generated by scripts/generate-reference.ts — do not edit manually
+- Symbols are documented in the order they appear in the barrel file
+- Declaration text is extracted from the TypeScript AST; method bodies are stripped
+- Type-only exports are labeled as "Type"; namespace exports include member listings
+
+Exported Symbols:
+GraphQLClient
+
+Import Path: webiny/admin/graphql-client
+
+Related Documents:
+- docs/developer-docs/6.0.x/basic/di.mdx — DI pattern used by all abstractions
+- docs/developer-docs/6.0.x/basic/result.mdx — Result type used in use case returns
+
+Tone Guidelines:
+- This is a reference page — terse, API-focused, no prose beyond what's necessary
+- Code blocks are the primary content; descriptions serve only to clarify intent
+- Do not add analogies or long explanations — link to guide pages for those
diff --git a/docs/developer-docs/6.0.x/reference/admin/graphql-client.mdx b/docs/developer-docs/6.0.x/reference/admin/graphql-client.mdx
new file mode 100644
index 000000000..c7494f3d6
--- /dev/null
+++ b/docs/developer-docs/6.0.x/reference/admin/graphql-client.mdx
@@ -0,0 +1,66 @@
+---
+id: ywrtaw4v
+title: Graphql Client
+description: "Reference for webiny/admin/graphql-client"
+---
+
+import { Alert } from "@/components/Alert";
+import { SymbolList } from "@/components/SymbolList";
+
+
+
+- What is exported from `webiny/admin/graphql-client`?
+- How to import and use each exported item?
+
+
+
+## Overview
+
+This page documents everything exported from `webiny/admin/graphql-client`. Import any of the items below directly from this path in your Webiny extensions.
+
+
+
+## `GraphQLClient`
+
+**Abstraction** — imported from `webiny/admin/graphql-client`
+
+```typescript
+import { GraphQLClient } from "webiny/admin/graphql-client";
+```
+
+**Interface `GraphQLClient.Interface`:**
+
+```typescript
+interface GraphQLClient.Interface {
+ execute(params: GraphQLRequest): Promise;
+}
+```
+
+**Types:**
+
+```typescript
+namespace GraphQLClient {
+ type Headers = IHeaders;
+ type Interface = IGraphQLClient;
+ type Request = GraphQLRequest;
+}
+```
+
+**Usage:**
+
+```typescript extensions/MyImpl.ts
+import { GraphQLClient } from "webiny/admin/graphql-client";
+
+class MyImpl implements MyUseCase.Interface {
+ public constructor(private graphQLClient: GraphQLClient.Interface) {}
+
+ public async execute(/* ... */): Promise {
+ await this.graphQLClient.execute(/* ... */);
+ }
+}
+
+export default MyUseCase.createImplementation({
+ implementation: MyImpl,
+ dependencies: [GraphQLClient]
+});
+```
diff --git a/docs/developer-docs/6.0.x/reference/admin/graphqlClient.ai.txt b/docs/developer-docs/6.0.x/reference/admin/graphqlClient.ai.txt
new file mode 100644
index 000000000..f403fce26
--- /dev/null
+++ b/docs/developer-docs/6.0.x/reference/admin/graphqlClient.ai.txt
@@ -0,0 +1,25 @@
+AI Context: GraphQL Client (reference/admin/graphqlClient.mdx)
+
+Source of Information:
+1. packages/webiny/src/admin/graphqlClient.ts — barrel re-export file
+2. /Users/adrian/dev/wby-next/packages/app/src/features/graphqlClient/abstractions.ts — originating source
+
+Key Documentation Decisions:
+- This file is auto-generated by scripts/generate-reference.ts — do not edit manually
+- Symbols are documented in the order they appear in the barrel file
+- Declaration text is extracted from the TypeScript AST; method bodies are stripped
+- Type-only exports are labeled as "Type"; namespace exports include member listings
+
+Exported Symbols:
+GraphQLClient
+
+Import Path: webiny/admin/graphqlClient
+
+Related Documents:
+- docs/developer-docs/6.0.x/basic/di.mdx — DI pattern used by all abstractions
+- docs/developer-docs/6.0.x/basic/result.mdx — Result type used in use case returns
+
+Tone Guidelines:
+- This is a reference page — terse, API-focused, no prose beyond what's necessary
+- Code blocks are the primary content; descriptions serve only to clarify intent
+- Do not add analogies or long explanations — link to guide pages for those
diff --git a/docs/developer-docs/6.0.x/reference/admin/graphqlClient.mdx b/docs/developer-docs/6.0.x/reference/admin/graphqlClient.mdx
new file mode 100644
index 000000000..26db5c331
--- /dev/null
+++ b/docs/developer-docs/6.0.x/reference/admin/graphqlClient.mdx
@@ -0,0 +1,67 @@
+---
+id: ywrtaw4v
+title: GraphQL Client
+description: "GraphQL client hooks and utilities"
+---
+
+import { Alert } from "@/components/Alert";
+import { SymbolList } from "@/components/SymbolList";
+
+
+
+- What is exported from `webiny/admin/graphqlClient`?
+- How to import and use each exported item?
+
+
+
+## Overview
+
+This page documents everything exported from `webiny/admin/graphqlClient`. Import any of the items below directly from this path in your Webiny extensions.
+
+
+
+## `GraphQLClient`
+
+**Abstraction** — imported from `webiny/admin/graphqlClient`
+
+```typescript
+import { GraphQLClient } from "webiny/admin/graphqlClient";
+```
+
+**Interface `GraphQLClient.Interface`:**
+
+```typescript
+interface GraphQLClient.Interface {
+ execute(params: GraphQLRequest): Promise;
+}
+```
+
+**Types:**
+
+```typescript
+namespace GraphQLClient {
+ type Headers = IHeaders;
+ type Interface = IGraphQLClient;
+ type Request = GraphQLRequest;
+}
+```
+
+**Usage:**
+
+```typescript
+// extensions/MyImpl.ts
+import { GraphQLClient } from "webiny/admin/graphqlClient";
+
+class MyImpl implements MyUseCase.Interface {
+ public constructor(private graphQLClient: GraphQLClient.Interface) {}
+
+ public async execute(/* ... */): Promise {
+ await this.graphQLClient.execute(/* ... */);
+ }
+}
+
+export default MyUseCase.createImplementation({
+ implementation: MyImpl,
+ dependencies: [GraphQLClient]
+});
+```
diff --git a/docs/developer-docs/6.0.x/reference/admin/lexical.ai.txt b/docs/developer-docs/6.0.x/reference/admin/lexical.ai.txt
new file mode 100644
index 000000000..321778c84
--- /dev/null
+++ b/docs/developer-docs/6.0.x/reference/admin/lexical.ai.txt
@@ -0,0 +1,26 @@
+AI Context: Lexical Editor (reference/admin/lexical.mdx)
+
+Source of Information:
+1. packages/webiny/src/admin/lexical.ts — barrel re-export file
+2. /Users/adrian/dev/wby-next/packages/lexical-editor/src/hooks/index.ts — originating source
+3. /Users/adrian/dev/wby-next/packages/lexical-editor/src/types.ts — originating source
+
+Key Documentation Decisions:
+- This file is auto-generated by scripts/generate-reference.ts — do not edit manually
+- Symbols are documented in the order they appear in the barrel file
+- Declaration text is extracted from the TypeScript AST; method bodies are stripped
+- Type-only exports are labeled as "Type"; namespace exports include member listings
+
+Exported Symbols:
+getNodeFromSelection, useCurrentElement, useCurrentSelection, useDeriveValueFromSelection, useRichTextEditor, useFontColorPicker, useTextAlignmentAction, useTypographyAction, useIsMounted, Klass, LexicalNode
+
+Import Path: webiny/admin/lexical
+
+Related Documents:
+- docs/developer-docs/6.0.x/basic/di.mdx — DI pattern used by all abstractions
+- docs/developer-docs/6.0.x/basic/result.mdx — Result type used in use case returns
+
+Tone Guidelines:
+- This is a reference page — terse, API-focused, no prose beyond what's necessary
+- Code blocks are the primary content; descriptions serve only to clarify intent
+- Do not add analogies or long explanations — link to guide pages for those
diff --git a/docs/developer-docs/6.0.x/reference/admin/lexical.mdx b/docs/developer-docs/6.0.x/reference/admin/lexical.mdx
new file mode 100644
index 000000000..ba297b811
--- /dev/null
+++ b/docs/developer-docs/6.0.x/reference/admin/lexical.mdx
@@ -0,0 +1,252 @@
+---
+id: ywrtaw4v
+title: Lexical Editor
+description: "Lexical editor components and hooks"
+---
+
+import { Alert } from "@/components/Alert";
+import { SymbolList } from "@/components/SymbolList";
+
+
+
+- What is exported from `webiny/admin/lexical`?
+- How to import and use each exported item?
+
+
+
+## Overview
+
+This page documents everything exported from `webiny/admin/lexical`. Import any of the items below directly from this path in your Webiny extensions.
+
+**Components**
+
+
+
+**Hooks**
+
+
+
+**Types**
+
+
+
+**Other**
+
+
+
+## Components
+
+### `LexicalNode`
+
+**Type** — imported from `webiny/admin/lexical`
+
+```typescript
+import type { LexicalNode } from "webiny/admin/lexical";
+```
+
+```typescript
+export declare class LexicalNode {
+ ["constructor"]: KlassConstructor;
+ __type: string;
+ __key: string;
+ __parent: null | NodeKey;
+ __prev: null | NodeKey;
+ __next: null | NodeKey;
+ __state?: NodeState;
+ static getType(): string;
+ static clone(_data: unknown): LexicalNode;
+ $config(): BaseStaticNodeConfig;
+ config>(
+ type: Type,
+ config: Config
+ ): StaticNodeConfigRecord;
+ afterCloneFrom(prevNode: this): void;
+ static importDOM?: () => DOMConversionMap | null;
+ constructor(key?: NodeKey);
+ getType(): string;
+ isInline(): boolean;
+ isAttached(): boolean;
+ isSelected(selection?: null | BaseSelection): boolean;
+ getKey(): NodeKey;
+ getIndexWithinParent(): number;
+ getParent(): T | null;
+ getParentOrThrow(): T;
+ getTopLevelElement(): ElementNode | DecoratorNode | null;
+ getTopLevelElementOrThrow(): ElementNode | DecoratorNode;
+ getParents(): Array;
+ getParentKeys(): Array;
+ getPreviousSibling(): T | null;
+ getPreviousSiblings(): Array;
+ getNextSibling(): T | null;
+ getNextSiblings(): Array;
+ getCommonAncestor(node: LexicalNode): T | null;
+ is(object: LexicalNode | null | undefined): boolean;
+ isBefore(targetNode: LexicalNode): boolean;
+ isParentOf(targetNode: LexicalNode): boolean;
+ getNodesBetween(targetNode: LexicalNode): Array;
+ isDirty(): boolean;
+ getLatest(): this;
+ getWritable(): this;
+ getTextContent(): string;
+ getTextContentSize(): number;
+ createDOM(_config: EditorConfig, _editor: LexicalEditor): HTMLElement;
+ updateDOM(_prevNode: unknown, _dom: HTMLElement, _config: EditorConfig): boolean;
+ exportDOM(editor: LexicalEditor): DOMExportOutput;
+ exportJSON(): SerializedLexicalNode;
+ static importJSON(_serializedNode: SerializedLexicalNode): LexicalNode;
+ updateFromJSON(serializedNode: LexicalUpdateJSON): this;
+ static transform(): ((node: LexicalNode) => void) | null;
+ remove(preserveEmptyParent?: boolean): void;
+ replace(replaceWith: N, includeChildren?: boolean): N;
+ insertAfter(nodeToInsert: LexicalNode, restoreSelection?: boolean): LexicalNode;
+ insertBefore(nodeToInsert: LexicalNode, restoreSelection?: boolean): LexicalNode;
+ isParentRequired(): boolean;
+ createParentElementNode(): ElementNode;
+ selectStart(): RangeSelection;
+ selectEnd(): RangeSelection;
+ selectPrevious(anchorOffset?: number, focusOffset?: number): RangeSelection;
+ selectNext(anchorOffset?: number, focusOffset?: number): RangeSelection;
+ markDirty(): void;
+ reconcileObservedMutation(dom: HTMLElement, editor: LexicalEditor): void;
+}
+```
+
+## Hooks
+
+### `useCurrentElement`
+
+**Function** — imported from `webiny/admin/lexical`
+
+```typescript
+import { useCurrentElement } from "webiny/admin/lexical";
+```
+
+```typescript
+export function useCurrentElement();
+```
+
+### `useCurrentSelection`
+
+**Function** — imported from `webiny/admin/lexical`
+
+```typescript
+import { useCurrentSelection } from "webiny/admin/lexical";
+```
+
+```typescript
+export function useCurrentSelection();
+```
+
+### `useDeriveValueFromSelection`
+
+**Function** — imported from `webiny/admin/lexical`
+
+```typescript
+import { useDeriveValueFromSelection } from "webiny/admin/lexical";
+```
+
+```typescript
+export function useDeriveValueFromSelection(generator: Generator);
+```
+
+### `useFontColorPicker`
+
+**Function** — imported from `webiny/admin/lexical`
+
+```typescript
+import { useFontColorPicker } from "webiny/admin/lexical";
+```
+
+```typescript
+export function useFontColorPicker();
+```
+
+### `useIsMounted`
+
+**Function** — imported from `webiny/admin/lexical`
+
+```typescript
+import { useIsMounted } from "webiny/admin/lexical";
+```
+
+```typescript
+export function useIsMounted();
+```
+
+### `useRichTextEditor`
+
+**Function** — imported from `webiny/admin/lexical`
+
+```typescript
+import { useRichTextEditor } from "webiny/admin/lexical";
+```
+
+```typescript
+export function useRichTextEditor();
+```
+
+### `useTextAlignmentAction`
+
+**Function** — imported from `webiny/admin/lexical`
+
+```typescript
+import { useTextAlignmentAction } from "webiny/admin/lexical";
+```
+
+```typescript
+export function useTextAlignmentAction();
+```
+
+### `useTypographyAction`
+
+**Function** — imported from `webiny/admin/lexical`
+
+```typescript
+import { useTypographyAction } from "webiny/admin/lexical";
+```
+
+```typescript
+export function useTypographyAction();
+```
+
+## Types
+
+### `Klass`
+
+**Type** — imported from `webiny/admin/lexical`
+
+```typescript
+import type { Klass } from "webiny/admin/lexical";
+```
+
+```typescript
+export type Klass =
+ InstanceType extends T
+ ? T["constructor"]
+ : GenericConstructor & T["constructor"];
+```
+
+## Other
+
+### `getNodeFromSelection`
+
+**Function** — imported from `webiny/admin/lexical`
+
+```typescript
+import { getNodeFromSelection } from "webiny/admin/lexical";
+```
+
+```typescript
+export function getNodeFromSelection(selection: RangeSelection);
+```
diff --git a/docs/developer-docs/6.0.x/reference/admin/local-storage.ai.txt b/docs/developer-docs/6.0.x/reference/admin/local-storage.ai.txt
new file mode 100644
index 000000000..088fe4abb
--- /dev/null
+++ b/docs/developer-docs/6.0.x/reference/admin/local-storage.ai.txt
@@ -0,0 +1,26 @@
+AI Context: Local Storage (reference/admin/local-storage.mdx)
+
+Source of Information:
+1. packages/webiny/src/admin/local-storage.ts — barrel re-export file
+2. /Users/adrian/dev/wby-next/packages/app/src/features/localStorage/abstractions.ts — originating source
+3. /Users/adrian/dev/wby-next/packages/app/src/presentation/localStorage/index.ts — originating source
+
+Key Documentation Decisions:
+- This file is auto-generated by scripts/generate-reference.ts — do not edit manually
+- Symbols are documented in the order they appear in the barrel file
+- Declaration text is extracted from the TypeScript AST; method bodies are stripped
+- Type-only exports are labeled as "Type"; namespace exports include member listings
+
+Exported Symbols:
+LocalStorage, useLocalStorage, useLocalStorageValue, useLocalStorageValues
+
+Import Path: webiny/admin/local-storage
+
+Related Documents:
+- docs/developer-docs/6.0.x/basic/di.mdx — DI pattern used by all abstractions
+- docs/developer-docs/6.0.x/basic/result.mdx — Result type used in use case returns
+
+Tone Guidelines:
+- This is a reference page — terse, API-focused, no prose beyond what's necessary
+- Code blocks are the primary content; descriptions serve only to clarify intent
+- Do not add analogies or long explanations — link to guide pages for those
diff --git a/docs/developer-docs/6.0.x/reference/admin/local-storage.mdx b/docs/developer-docs/6.0.x/reference/admin/local-storage.mdx
new file mode 100644
index 000000000..2d47af6ac
--- /dev/null
+++ b/docs/developer-docs/6.0.x/reference/admin/local-storage.mdx
@@ -0,0 +1,93 @@
+---
+id: ywrtaw4v
+title: Local Storage
+description: "Reference for webiny/admin/local-storage"
+---
+
+import { Alert } from "@/components/Alert";
+import { SymbolList } from "@/components/SymbolList";
+
+
+
+- What is exported from `webiny/admin/local-storage`?
+- How to import and use each exported item?
+
+
+
+## Overview
+
+This page documents everything exported from `webiny/admin/local-storage`. Import any of the items below directly from this path in your Webiny extensions.
+
+**Components**
+
+
+
+**Hooks**
+
+
+
+## Components
+
+### `LocalStorage`
+
+**Constant** — imported from `webiny/admin/local-storage`
+
+```typescript
+import { LocalStorage } from "webiny/admin/local-storage";
+```
+
+```typescript
+export const LocalStorage = new Abstraction("LocalStorage");
+```
+
+## Hooks
+
+### `useLocalStorage`
+
+**Function** — imported from `webiny/admin/local-storage`
+
+Returns the LocalStorage instance from DI.
+Useful when you want to call service methods imperatively inside components.
+
+```typescript
+import { useLocalStorage } from "webiny/admin/local-storage";
+```
+
+```typescript
+export function useLocalStorage(): LocalStorage.Interface;
+```
+
+### `useLocalStorageValue`
+
+**Function** — imported from `webiny/admin/local-storage`
+
+```typescript
+import { useLocalStorageValue } from "webiny/admin/local-storage";
+```
+
+```typescript
+export function useLocalStorageValue(key: string): T | undefined;
+```
+
+### `useLocalStorageValues`
+
+**Function** — imported from `webiny/admin/local-storage`
+
+Observes multiple keys in LocalStorage and returns an object of { key: value }.
+Re-renders when any of the observed keys change.
+
+```typescript
+import { useLocalStorageValues } from "webiny/admin/local-storage";
+```
+
+```typescript
+export function useLocalStorageValues>(
+ keys: (keyof T & string)[]
+): Partial;
+```
diff --git a/docs/developer-docs/6.0.x/reference/admin/localStorage.ai.txt b/docs/developer-docs/6.0.x/reference/admin/localStorage.ai.txt
new file mode 100644
index 000000000..28fe2bb45
--- /dev/null
+++ b/docs/developer-docs/6.0.x/reference/admin/localStorage.ai.txt
@@ -0,0 +1,26 @@
+AI Context: Local Storage (reference/admin/localStorage.mdx)
+
+Source of Information:
+1. packages/webiny/src/admin/localStorage.ts — barrel re-export file
+2. /Users/adrian/dev/wby-next/packages/app/src/features/localStorage/abstractions.ts — originating source
+3. /Users/adrian/dev/wby-next/packages/app/src/presentation/localStorage/index.ts — originating source
+
+Key Documentation Decisions:
+- This file is auto-generated by scripts/generate-reference.ts — do not edit manually
+- Symbols are documented in the order they appear in the barrel file
+- Declaration text is extracted from the TypeScript AST; method bodies are stripped
+- Type-only exports are labeled as "Type"; namespace exports include member listings
+
+Exported Symbols:
+LocalStorage, useLocalStorage, useLocalStorageValue, useLocalStorageValues
+
+Import Path: webiny/admin/localStorage
+
+Related Documents:
+- docs/developer-docs/6.0.x/basic/di.mdx — DI pattern used by all abstractions
+- docs/developer-docs/6.0.x/basic/result.mdx — Result type used in use case returns
+
+Tone Guidelines:
+- This is a reference page — terse, API-focused, no prose beyond what's necessary
+- Code blocks are the primary content; descriptions serve only to clarify intent
+- Do not add analogies or long explanations — link to guide pages for those
diff --git a/docs/developer-docs/6.0.x/reference/admin/localStorage.mdx b/docs/developer-docs/6.0.x/reference/admin/localStorage.mdx
new file mode 100644
index 000000000..728d3800e
--- /dev/null
+++ b/docs/developer-docs/6.0.x/reference/admin/localStorage.mdx
@@ -0,0 +1,84 @@
+---
+id: ywrtaw4v
+title: Local Storage
+description: "Local storage abstraction and hooks"
+---
+
+import { Alert } from "@/components/Alert";
+import { SymbolList } from "@/components/SymbolList";
+
+
+
+- What is exported from `webiny/admin/localStorage`?
+- How to import and use each exported item?
+
+
+
+## Overview
+
+This page documents everything exported from `webiny/admin/localStorage`. Import any of the items below directly from this path in your Webiny extensions.
+
+
+
+## `LocalStorage`
+
+**Constant** — imported from `webiny/admin/localStorage`
+
+```typescript
+import { LocalStorage } from "webiny/admin/localStorage";
+```
+
+```typescript
+export const LocalStorage = new Abstraction("LocalStorage");
+```
+
+## `useLocalStorage`
+
+**Function** — imported from `webiny/admin/localStorage`
+
+Returns the LocalStorage instance from DI.
+Useful when you want to call service methods imperatively inside components.
+
+```typescript
+import { useLocalStorage } from "webiny/admin/localStorage";
+```
+
+```typescript
+export function useLocalStorage(): LocalStorage.Interface;
+```
+
+## `useLocalStorageValue`
+
+**Function** — imported from `webiny/admin/localStorage`
+
+```typescript
+import { useLocalStorageValue } from "webiny/admin/localStorage";
+```
+
+```typescript
+export function useLocalStorageValue(key: string): T | undefined;
+```
+
+## `useLocalStorageValues`
+
+**Function** — imported from `webiny/admin/localStorage`
+
+Observes multiple keys in LocalStorage and returns an object of { key: value }.
+Re-renders when any of the observed keys change.
+
+```typescript
+import { useLocalStorageValues } from "webiny/admin/localStorage";
+```
+
+```typescript
+export function useLocalStorageValues>(
+ keys: (keyof T & string)[]
+): Partial;
+```
diff --git a/docs/developer-docs/6.0.x/reference/admin/router.ai.txt b/docs/developer-docs/6.0.x/reference/admin/router.ai.txt
new file mode 100644
index 000000000..2c348e703
--- /dev/null
+++ b/docs/developer-docs/6.0.x/reference/admin/router.ai.txt
@@ -0,0 +1,26 @@
+AI Context: Router (reference/admin/router.mdx)
+
+Source of Information:
+1. packages/webiny/src/admin/router.ts — barrel re-export file
+2. /Users/adrian/dev/wby-next/packages/app/src/features/router/Route.ts — originating source
+3. /Users/adrian/dev/wby-next/packages/app/src/presentation/router/index.ts — originating source
+
+Key Documentation Decisions:
+- This file is auto-generated by scripts/generate-reference.ts — do not edit manually
+- Symbols are documented in the order they appear in the barrel file
+- Declaration text is extracted from the TypeScript AST; method bodies are stripped
+- Type-only exports are labeled as "Type"; namespace exports include member listings
+
+Exported Symbols:
+Route, useRoute, useRouter
+
+Import Path: webiny/admin/router
+
+Related Documents:
+- docs/developer-docs/6.0.x/basic/di.mdx — DI pattern used by all abstractions
+- docs/developer-docs/6.0.x/basic/result.mdx — Result type used in use case returns
+
+Tone Guidelines:
+- This is a reference page — terse, API-focused, no prose beyond what's necessary
+- Code blocks are the primary content; descriptions serve only to clarify intent
+- Do not add analogies or long explanations — link to guide pages for those
diff --git a/docs/developer-docs/6.0.x/reference/admin/router.mdx b/docs/developer-docs/6.0.x/reference/admin/router.mdx
new file mode 100644
index 000000000..231cc1977
--- /dev/null
+++ b/docs/developer-docs/6.0.x/reference/admin/router.mdx
@@ -0,0 +1,94 @@
+---
+id: ywrtaw4v
+title: Router
+description: "Router components and hooks"
+---
+
+import { Alert } from "@/components/Alert";
+import { SymbolList } from "@/components/SymbolList";
+
+
+
+- What is exported from `webiny/admin/router`?
+- How to import and use each exported item?
+
+
+
+## Overview
+
+This page documents everything exported from `webiny/admin/router`. Import any of the items below directly from this path in your Webiny extensions.
+
+**Components**
+
+
+
+**Hooks**
+
+
+
+## Components
+
+### `Route`
+
+**Class** — imported from `webiny/admin/router`
+
+```typescript
+import { Route } from "webiny/admin/router";
+```
+
+```typescript
+export class Route {
+ private readonly route: RouteParams;
+ private readonly schema: TParams extends RouteParamsDefinition
+ ? RouteParamsInfer
+ : undefined;
+ constructor(route: RouteParams);
+ get name();
+ get path();
+ get params(): TParams extends RouteParamsDefinition ? RouteParamsInfer : undefined;
+ private coerceParams>(shape: T);
+}
+```
+
+## Hooks
+
+### `useRoute`
+
+**Function** — imported from `webiny/admin/router`
+
+```typescript
+import { useRoute } from "webiny/admin/router";
+```
+
+```typescript
+export function useRoute(
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
+ route?: Route
+);
+```
+
+### `useRouter`
+
+**Constant** — imported from `webiny/admin/router`
+
+```typescript
+import { useRouter } from "webiny/admin/router";
+```
+
+```typescript
+export const useRouter = () => {
+ const { presenter } = useFeature(RouterFeature);
+ const container = useContainer();
+ const registry = container.resolve(RouteElementRegistry);
+
+ return {
+ goToRoute: presenter.goToRoute.bind(presenter),
+ getLink: presenter.getLink.bind(presenter),
+ onRouteExit: presenter.onRouteExit.bind(presenter),
+ setRoutes: (routes: Reac
+```
diff --git a/docs/developer-docs/6.0.x/reference/admin/security.ai.txt b/docs/developer-docs/6.0.x/reference/admin/security.ai.txt
new file mode 100644
index 000000000..7c3d48631
--- /dev/null
+++ b/docs/developer-docs/6.0.x/reference/admin/security.ai.txt
@@ -0,0 +1,31 @@
+AI Context: Security (reference/admin/security.mdx)
+
+Source of Information:
+1. packages/webiny/src/admin/security.ts — barrel re-export file
+2. /Users/adrian/dev/wby-next/packages/app/src/errors/abstractions.ts — originating source
+3. /Users/adrian/dev/wby-next/packages/app-admin/src/features/security/LogIn/index.ts — originating source
+4. /Users/adrian/dev/wby-next/packages/app-admin/src/features/security/LogOut/index.ts — originating source
+5. /Users/adrian/dev/wby-next/packages/app-admin/src/features/security/AuthenticationContext/index.ts — originating source
+6. /Users/adrian/dev/wby-next/packages/app-admin/src/features/security/IdentityContext/index.ts — originating source
+7. /Users/adrian/dev/wby-next/packages/app-admin/src/presentation/security/hooks/useAuthentication.ts — originating source
+8. /Users/adrian/dev/wby-next/packages/app-admin/src/presentation/security/hooks/useIdentity.ts — originating source
+
+Key Documentation Decisions:
+- This file is auto-generated by scripts/generate-reference.ts — do not edit manually
+- Symbols are documented in the order they appear in the barrel file
+- Declaration text is extracted from the TypeScript AST; method bodies are stripped
+- Type-only exports are labeled as "Type"; namespace exports include member listings
+
+Exported Symbols:
+AuthenticationErrorEventHandler, LogInUseCase, LogOutUseCase, AuthenticationContext, IdentityContext, useAuthentication, useIdentity
+
+Import Path: webiny/admin/security
+
+Related Documents:
+- docs/developer-docs/6.0.x/basic/di.mdx — DI pattern used by all abstractions
+- docs/developer-docs/6.0.x/basic/result.mdx — Result type used in use case returns
+
+Tone Guidelines:
+- This is a reference page — terse, API-focused, no prose beyond what's necessary
+- Code blocks are the primary content; descriptions serve only to clarify intent
+- Do not add analogies or long explanations — link to guide pages for those
diff --git a/docs/developer-docs/6.0.x/reference/admin/security.mdx b/docs/developer-docs/6.0.x/reference/admin/security.mdx
new file mode 100644
index 000000000..33835881d
--- /dev/null
+++ b/docs/developer-docs/6.0.x/reference/admin/security.mdx
@@ -0,0 +1,294 @@
+---
+id: ywrtaw4v
+title: Security
+description: "Admin security: authentication, identity, permissions"
+---
+
+import { Alert } from "@/components/Alert";
+import { SymbolList } from "@/components/SymbolList";
+
+
+
+- What use cases are available in `webiny/admin/security`?
+- Which event handlers can you implement?
+- How to import and use each exported item?
+
+
+
+## Overview
+
+This page documents everything exported from `webiny/admin/security`. Import any of the items below directly from this path in your Webiny extensions.
+
+**Hooks**
+
+
+
+**Other**
+
+
+
+## Hooks
+
+### `useAuthentication`
+
+**Function** — imported from `webiny/admin/security`
+
+```typescript
+import { useAuthentication } from "webiny/admin/security";
+```
+
+```typescript
+export function useAuthentication(): IUseAuthenticationReturn;
+```
+
+### `useIdentity`
+
+**Function** — imported from `webiny/admin/security`
+
+```typescript
+import { useIdentity } from "webiny/admin/security";
+```
+
+```typescript
+export function useIdentity(): IUseIdentityReturn;
+```
+
+## Other
+
+### `AuthenticationContext`
+
+**Abstraction** — imported from `webiny/admin/security`
+
+```typescript
+import { AuthenticationContext } from "webiny/admin/security";
+```
+
+**Interface `AuthenticationContext.Interface`:**
+
+```typescript
+interface AuthenticationContext.Interface {
+ clear(): void;
+ getIdToken: IIdTokenProvider;
+ setIdTokenProvider(provider: IIdTokenProvider): void;
+ setLogoutCallback(callback: ILogoutCallback): void;
+ getLogoutCallback(): ILogoutCallback;
+}
+```
+
+**Types:**
+
+```typescript
+namespace AuthenticationContext {
+ type Interface = IAuthenticationContext;
+ type IdTokenProvider = IIdTokenProvider;
+ type LogoutCallback = ILogoutCallback;
+}
+```
+
+**Usage:**
+
+```typescript extensions/MyImpl.ts
+import { AuthenticationContext } from "webiny/admin/security";
+
+class MyImpl implements MyUseCase.Interface {
+ public constructor(private authenticationContext: AuthenticationContext.Interface) {}
+
+ public async execute(/* ... */): Promise {
+ this.authenticationContext.clear(/* ... */);
+ }
+}
+
+export default MyUseCase.createImplementation({
+ implementation: MyImpl,
+ dependencies: [AuthenticationContext]
+});
+```
+
+### `AuthenticationErrorEventHandler`
+
+**Event Handler Abstraction** — imported from `webiny/admin/security`
+
+```typescript
+import { AuthenticationErrorEventHandler } from "webiny/admin/security";
+```
+
+**Interface `AuthenticationErrorEventHandler.Interface`:**
+
+```typescript
+interface AuthenticationErrorEventHandler.Interface {
+ handle(event: AuthenticationErrorEvent): Promise;
+}
+```
+
+**Types:**
+
+```typescript
+namespace AuthenticationErrorEventHandler {
+ type Interface = IEventHandler;
+ type Event = AuthenticationErrorEvent;
+}
+```
+
+**Usage:**
+
+```typescript extensions/MyHandler.ts
+import { AuthenticationErrorEventHandler } from "webiny/admin/security";
+
+class MyHandler implements AuthenticationErrorEventHandler.Interface {
+ public constructor(/* inject dependencies here */) {}
+
+ public async handle(event: AuthenticationErrorEventHandler.Event): Promise {
+ // implementation
+ }
+}
+
+export default AuthenticationErrorEventHandler.createImplementation({
+ implementation: MyHandler,
+ dependencies: []
+});
+```
+
+### `IdentityContext`
+
+**Abstraction** — imported from `webiny/admin/security`
+
+```typescript
+import { IdentityContext } from "webiny/admin/security";
+```
+
+**Interface `IdentityContext.Interface`:**
+
+```typescript
+interface IdentityContext.Interface {
+ getIdentity(): Identity;
+ setIdentity(identity: Identity): void;
+ clear(): void;
+}
+```
+
+**Types:**
+
+```typescript
+namespace IdentityContext {
+ type Interface = IIdentityContext;
+}
+```
+
+**Usage:**
+
+```typescript extensions/MyImpl.ts
+import { IdentityContext } from "webiny/admin/security";
+
+class MyImpl implements MyUseCase.Interface {
+ public constructor(private identityContext: IdentityContext.Interface) {}
+
+ public async execute(/* ... */): Promise {
+ this.identityContext.getIdentity(/* ... */);
+ }
+}
+
+export default MyUseCase.createImplementation({
+ implementation: MyImpl,
+ dependencies: [IdentityContext]
+});
+```
+
+### `LogInUseCase`
+
+**Use Case Abstraction** — imported from `webiny/admin/security`
+
+```typescript
+import { LogInUseCase } from "webiny/admin/security";
+```
+
+**Interface `LogInUseCase.Interface`:**
+
+```typescript
+interface LogInUseCase.Interface {
+ execute(params: ILoginParams): Promise;
+}
+```
+
+**Types:**
+
+```typescript
+namespace LogInUseCase {
+ type Interface = ILogInUseCase;
+ type Params = ILoginParams;
+}
+```
+
+**Usage:**
+
+```typescript extensions/MyImpl.ts
+import { LogInUseCase } from "webiny/admin/security";
+
+class MyImpl implements MyUseCase.Interface {
+ public constructor(private logInUseCase: LogInUseCase.Interface) {}
+
+ public async execute(/* ... */): Promise {
+ await this.logInUseCase.execute(/* ... */);
+ }
+}
+
+export default MyUseCase.createImplementation({
+ implementation: MyImpl,
+ dependencies: [LogInUseCase]
+});
+```
+
+### `LogOutUseCase`
+
+**Use Case Abstraction** — imported from `webiny/admin/security`
+
+```typescript
+import { LogOutUseCase } from "webiny/admin/security";
+```
+
+**Interface `LogOutUseCase.Interface`:**
+
+```typescript
+interface LogOutUseCase.Interface {
+ execute(): Promise;
+}
+```
+
+**Types:**
+
+```typescript
+namespace LogOutUseCase {
+ type Interface = ILogOutUseCase;
+}
+```
+
+**Usage:**
+
+```typescript extensions/MyImpl.ts
+import { LogOutUseCase } from "webiny/admin/security";
+
+class MyImpl implements MyUseCase.Interface {
+ public constructor(private logOutUseCase: LogOutUseCase.Interface) {}
+
+ public async execute(/* ... */): Promise {
+ await this.logOutUseCase.execute(/* ... */);
+ }
+}
+
+export default MyUseCase.createImplementation({
+ implementation: MyImpl,
+ dependencies: [LogOutUseCase]
+});
+```
diff --git a/docs/developer-docs/6.0.x/reference/admin/tenancy.ai.txt b/docs/developer-docs/6.0.x/reference/admin/tenancy.ai.txt
new file mode 100644
index 000000000..205ae1e30
--- /dev/null
+++ b/docs/developer-docs/6.0.x/reference/admin/tenancy.ai.txt
@@ -0,0 +1,26 @@
+AI Context: Tenancy (reference/admin/tenancy.mdx)
+
+Source of Information:
+1. packages/webiny/src/admin/tenancy.ts — barrel re-export file
+2. /Users/adrian/dev/wby-next/packages/app-admin/src/features/tenancy/abstractions.ts — originating source
+3. /Users/adrian/dev/wby-next/packages/app-admin/src/presentation/tenancy/useTenantContext.ts — originating source
+
+Key Documentation Decisions:
+- This file is auto-generated by scripts/generate-reference.ts — do not edit manually
+- Symbols are documented in the order they appear in the barrel file
+- Declaration text is extracted from the TypeScript AST; method bodies are stripped
+- Type-only exports are labeled as "Type"; namespace exports include member listings
+
+Exported Symbols:
+TenantContext, useTenantContext
+
+Import Path: webiny/admin/tenancy
+
+Related Documents:
+- docs/developer-docs/6.0.x/basic/di.mdx — DI pattern used by all abstractions
+- docs/developer-docs/6.0.x/basic/result.mdx — Result type used in use case returns
+
+Tone Guidelines:
+- This is a reference page — terse, API-focused, no prose beyond what's necessary
+- Code blocks are the primary content; descriptions serve only to clarify intent
+- Do not add analogies or long explanations — link to guide pages for those
diff --git a/docs/developer-docs/6.0.x/reference/admin/tenancy.mdx b/docs/developer-docs/6.0.x/reference/admin/tenancy.mdx
new file mode 100644
index 000000000..b7ba2b6dc
--- /dev/null
+++ b/docs/developer-docs/6.0.x/reference/admin/tenancy.mdx
@@ -0,0 +1,55 @@
+---
+id: ywrtaw4v
+title: Tenancy
+description: "Admin tenancy hooks and context"
+---
+
+import { Alert } from "@/components/Alert";
+import { SymbolList } from "@/components/SymbolList";
+
+
+
+- What is exported from `webiny/admin/tenancy`?
+- How to import and use each exported item?
+
+
+
+## Overview
+
+This page documents everything exported from `webiny/admin/tenancy`. Import any of the items below directly from this path in your Webiny extensions.
+
+**Components**
+
+
+
+**Hooks**
+
+
+
+## Components
+
+### `TenantContext`
+
+**Constant** — imported from `webiny/admin/tenancy`
+
+```typescript
+import { TenantContext } from "webiny/admin/tenancy";
+```
+
+```typescript
+export const TenantContext = new Abstraction("TenantContext");
+```
+
+## Hooks
+
+### `useTenantContext`
+
+**Function** — imported from `webiny/admin/tenancy`
+
+```typescript
+import { useTenantContext } from "webiny/admin/tenancy";
+```
+
+```typescript
+export function useTenantContext();
+```
diff --git a/docs/developer-docs/6.0.x/reference/admin/ui.ai.txt b/docs/developer-docs/6.0.x/reference/admin/ui.ai.txt
new file mode 100644
index 000000000..69a90bfa3
--- /dev/null
+++ b/docs/developer-docs/6.0.x/reference/admin/ui.ai.txt
@@ -0,0 +1,83 @@
+AI Context: UI (reference/admin/ui.mdx)
+
+Source of Information:
+1. packages/webiny/src/admin/ui.ts — barrel re-export file
+2. /Users/adrian/dev/wby-next/packages/admin-ui/src/Accordion/index.ts — originating source
+3. /Users/adrian/dev/wby-next/packages/admin-ui/src/Alert/index.ts — originating source
+4. /Users/adrian/dev/wby-next/packages/admin-ui/src/AutoComplete/index.ts — originating source
+5. /Users/adrian/dev/wby-next/packages/admin-ui/src/Avatar/index.ts — originating source
+6. /Users/adrian/dev/wby-next/packages/admin-ui/src/Button/index.ts — originating source
+7. /Users/adrian/dev/wby-next/packages/admin-ui/src/Card/index.ts — originating source
+8. /Users/adrian/dev/wby-next/packages/admin-ui/src/Checkbox/index.ts — originating source
+9. /Users/adrian/dev/wby-next/packages/admin-ui/src/CheckboxGroup/index.ts — originating source
+10. /Users/adrian/dev/wby-next/packages/admin-ui/src/CodeEditor/index.ts — originating source
+11. /Users/adrian/dev/wby-next/packages/admin-ui/src/ColorPicker/index.ts — originating source
+12. /Users/adrian/dev/wby-next/packages/admin-ui/src/DataList/index.ts — originating source
+13. /Users/adrian/dev/wby-next/packages/admin-ui/src/DataTable/index.ts — originating source
+14. /Users/adrian/dev/wby-next/packages/admin-ui/src/DelayedOnChange/index.ts — originating source
+15. /Users/adrian/dev/wby-next/packages/admin-ui/src/Dialog/index.ts — originating source
+16. /Users/adrian/dev/wby-next/packages/admin-ui/src/Drawer/index.ts — originating source
+17. /Users/adrian/dev/wby-next/packages/admin-ui/src/DropdownMenu/index.ts — originating source
+18. /Users/adrian/dev/wby-next/packages/admin-ui/src/DynamicFieldset/index.ts — originating source
+19. /Users/adrian/dev/wby-next/packages/admin-ui/src/FilePicker/index.ts — originating source
+20. /Users/adrian/dev/wby-next/packages/admin-ui/src/Grid/index.ts — originating source
+21. /Users/adrian/dev/wby-next/packages/admin-ui/src/HeaderBar/index.ts — originating source
+22. /Users/adrian/dev/wby-next/packages/admin-ui/src/Heading/index.ts — originating source
+23. /Users/adrian/dev/wby-next/packages/admin-ui/src/Icon/index.ts — originating source
+24. /Users/adrian/dev/wby-next/packages/admin-ui/src/IconPicker/index.ts — originating source
+25. /Users/adrian/dev/wby-next/packages/admin-ui/src/Image/index.ts — originating source
+26. /Users/adrian/dev/wby-next/packages/admin-ui/src/Input/index.ts — originating source
+27. /Users/adrian/dev/wby-next/packages/admin-ui/src/Label/index.ts — originating source
+28. /Users/adrian/dev/wby-next/packages/admin-ui/src/Link/index.ts — originating source
+29. /Users/adrian/dev/wby-next/packages/admin-ui/src/List/index.ts — originating source
+30. /Users/adrian/dev/wby-next/packages/admin-ui/src/Loader/index.ts — originating source
+31. /Users/adrian/dev/wby-next/packages/admin-ui/src/MultiAutoComplete/index.ts — originating source
+32. /Users/adrian/dev/wby-next/packages/admin-ui/src/MultiFilePicker/index.ts — originating source
+33. /Users/adrian/dev/wby-next/packages/admin-ui/src/Portal/index.ts — originating source
+34. /Users/adrian/dev/wby-next/packages/admin-ui/src/Popover/index.ts — originating source
+35. /Users/adrian/dev/wby-next/packages/admin-ui/src/ProgressBar/index.ts — originating source
+36. /Users/adrian/dev/wby-next/packages/admin-ui/src/RadioGroup/index.ts — originating source
+37. /Users/adrian/dev/wby-next/packages/admin-ui/src/RangeSlider/index.ts — originating source
+38. /Users/adrian/dev/wby-next/packages/admin-ui/src/Scrollbar/index.ts — originating source
+39. /Users/adrian/dev/wby-next/packages/admin-ui/src/ScrollArea/index.ts — originating source
+40. /Users/adrian/dev/wby-next/packages/admin-ui/src/SegmentedControl/index.ts — originating source
+41. /Users/adrian/dev/wby-next/packages/admin-ui/src/Select/index.ts — originating source
+42. /Users/adrian/dev/wby-next/packages/admin-ui/src/Separator/index.ts — originating source
+43. /Users/adrian/dev/wby-next/packages/admin-ui/src/Sidebar/index.ts — originating source
+44. /Users/adrian/dev/wby-next/packages/admin-ui/src/Skeleton/index.ts — originating source
+45. /Users/adrian/dev/wby-next/packages/admin-ui/src/Slider/index.ts — originating source
+46. /Users/adrian/dev/wby-next/packages/admin-ui/src/SteppedProgress/index.ts — originating source
+47. /Users/adrian/dev/wby-next/packages/admin-ui/src/Switch/index.ts — originating source
+48. /Users/adrian/dev/wby-next/packages/admin-ui/src/Table/index.ts — originating source
+49. /Users/adrian/dev/wby-next/packages/admin-ui/src/Tabs/index.ts — originating source
+50. /Users/adrian/dev/wby-next/packages/admin-ui/src/Tag/index.ts — originating source
+51. /Users/adrian/dev/wby-next/packages/admin-ui/src/Tags/index.ts — originating source
+52. /Users/adrian/dev/wby-next/packages/admin-ui/src/Text/index.ts — originating source
+53. /Users/adrian/dev/wby-next/packages/admin-ui/src/Textarea/index.ts — originating source
+54. /Users/adrian/dev/wby-next/packages/admin-ui/src/TimeAgo/index.ts — originating source
+55. /Users/adrian/dev/wby-next/packages/admin-ui/src/Toast/index.ts — originating source
+56. /Users/adrian/dev/wby-next/packages/admin-ui/src/Tooltip/index.ts — originating source
+57. /Users/adrian/dev/wby-next/packages/admin-ui/src/Tree/index.ts — originating source
+58. /Users/adrian/dev/wby-next/packages/admin-ui/src/Widget/index.ts — originating source
+59. /Users/adrian/dev/wby-next/packages/admin-ui/src/hooks/index.ts — originating source
+60. /Users/adrian/dev/wby-next/packages/app-admin/src/components/Dialogs/useDialogs.ts — originating source
+
+Key Documentation Decisions:
+- This file is auto-generated by scripts/generate-reference.ts — do not edit manually
+- Symbols are documented in the order they appear in the barrel file
+- Declaration text is extracted from the TypeScript AST; method bodies are stripped
+- Type-only exports are labeled as "Type"; namespace exports include member listings
+
+Exported Symbols:
+Accordion, Alert, AutoComplete, Avatar, Button, CopyButton, IconButton, Card, Checkbox, CheckboxGroup, CodeEditor, ColorPicker, CloneIcon, CreateIcon, DataList, DataListModal, DataListWithSections, DeleteIcon, DownloadIcon, EditIcon, FilterIcon, ListIcon, LoginIcon, NextPageIcon, OptionsIcon, PreviousPageIcon, RefreshIcon, SortIcon, UploadIcon, DataTable, DelayedOnChange, Dialog, Drawer, DropdownMenu, DynamicFieldset, FilePicker, Grid, HeaderBar, Heading, Icon, IconPicker, Image, Input, Label, Link, List, Loader, OverlayLoader, MultiAutoComplete, MultiFilePicker, Portal, Popover, ProgressBar, Radio, RadioGroup, RangeSlider, Scrollbar, ScrollArea, ScrollBar, SegmentedControl, Select, Separator, Sidebar, SidebarProvider, useSidebar, Skeleton, Slider, SteppedProgress, Switch, Table, Tabs, Tag, Tags, Text, Textarea, TimeAgo, Toast, useToast, Tooltip, Tree, Widget, useDisclosure, useDialogs
+
+Import Path: webiny/admin/ui
+
+Related Documents:
+- docs/developer-docs/6.0.x/basic/di.mdx — DI pattern used by all abstractions
+- docs/developer-docs/6.0.x/basic/result.mdx — Result type used in use case returns
+
+Tone Guidelines:
+- This is a reference page — terse, API-focused, no prose beyond what's necessary
+- Code blocks are the primary content; descriptions serve only to clarify intent
+- Do not add analogies or long explanations — link to guide pages for those
diff --git a/docs/developer-docs/6.0.x/reference/admin/ui.mdx b/docs/developer-docs/6.0.x/reference/admin/ui.mdx
new file mode 100644
index 000000000..b15da94de
--- /dev/null
+++ b/docs/developer-docs/6.0.x/reference/admin/ui.mdx
@@ -0,0 +1,1430 @@
+---
+id: ywrtaw4v
+title: UI
+description: "Admin UI component library"
+---
+
+import { Alert } from "@/components/Alert";
+import { SymbolList } from "@/components/SymbolList";
+
+
+
+- What is exported from `webiny/admin/ui`?
+- How to import and use each exported item?
+
+
+
+## Overview
+
+This page documents everything exported from `webiny/admin/ui`. Import any of the items below directly from this path in your Webiny extensions.
+
+**Components**
+
+
+
+**Hooks**
+
+
+
+## Components
+
+### `Accordion`
+
+**Constant** — imported from `webiny/admin/ui`
+
+```typescript
+import { Accordion } from "webiny/admin/ui";
+```
+
+```typescript
+export const Accordion = withStaticProps(DecoratableAccordion, {
+ Item: AccordionItem
+});
+```
+
+### `Alert`
+
+**Constant** — imported from `webiny/admin/ui`
+
+```typescript
+import { Alert } from "webiny/admin/ui";
+```
+
+```typescript
+const Alert = withStaticProps(makeDecoratable("AlertBase", AlertBase), {
+ Action: AlertAction
+});
+```
+
+### `AutoComplete`
+
+**Constant** — imported from `webiny/admin/ui`
+
+```typescript
+import { AutoComplete } from "webiny/admin/ui";
+```
+
+```typescript
+const AutoComplete = makeDecoratable("AutoComplete", DecoratableAutoComplete);
+```
+
+### `Avatar`
+
+**Constant** — imported from `webiny/admin/ui`
+
+```typescript
+import { Avatar } from "webiny/admin/ui";
+```
+
+```typescript
+const Avatar = withStaticProps(makeDecoratable("Avatar", AvatarBase), {
+ Fallback: AvatarFallback,
+ Image: AvatarImage
+});
+```
+
+### `Button`
+
+**Constant** — imported from `webiny/admin/ui`
+
+```typescript
+import { Button } from "webiny/admin/ui";
+```
+
+```typescript
+const Button = makeDecoratable("Button", ButtonBase);
+```
+
+### `Card`
+
+**Constant** — imported from `webiny/admin/ui`
+
+```typescript
+import { Card } from "webiny/admin/ui";
+```
+
+```typescript
+const Card = withStaticProps(DecoratableCard, {
+ ConfirmAction,
+ CancelAction,
+ Icon
+});
+```
+
+### `Checkbox`
+
+**Constant** — imported from `webiny/admin/ui`
+
+```typescript
+import { Checkbox } from "webiny/admin/ui";
+```
+
+```typescript
+const Checkbox = makeDecoratable("Checkbox", DecoratableCheckbox);
+```
+
+### `CheckboxGroup`
+
+**Constant** — imported from `webiny/admin/ui`
+
+```typescript
+import { CheckboxGroup } from "webiny/admin/ui";
+```
+
+```typescript
+const CheckboxGroup = makeDecoratable("CheckboxGroup", DecoratableCheckboxGroup);
+```
+
+### `CloneIcon`
+
+**Constant** — imported from `webiny/admin/ui`
+
+```typescript
+import { CloneIcon } from "webiny/admin/ui";
+```
+
+```typescript
+export const CloneIcon = (props: IconButtonProps) => {
+ return (
+ } label={"Clone"} />}
+ variant={"ghost"}
+ size={"sm"}
+ {...props}
+ />
+ );
+};
+```
+
+### `CodeEditor`
+
+**Constant** — imported from `webiny/admin/ui`
+
+```typescript
+import { CodeEditor } from "webiny/admin/ui";
+```
+
+```typescript
+const CodeEditor = makeDecoratable("CodeEditor", DecoratableCodeEditor);
+```
+
+### `ColorPicker`
+
+**Constant** — imported from `webiny/admin/ui`
+
+```typescript
+import { ColorPicker } from "webiny/admin/ui";
+```
+
+```typescript
+const ColorPicker = makeDecoratable("ColorPicker", DecoratableIconPicker);
+```
+
+### `CopyButton`
+
+**Constant** — imported from `webiny/admin/ui`
+
+```typescript
+import { CopyButton } from "webiny/admin/ui";
+```
+
+```typescript
+const CopyButton = makeDecoratable("CopyButton", CopyButtonBase);
+```
+
+### `CreateIcon`
+
+**Constant** — imported from `webiny/admin/ui`
+
+```typescript
+import { CreateIcon } from "webiny/admin/ui";
+```
+
+```typescript
+export const CreateIcon = (props: IconButtonProps) => {
+ return (
+ } label={"Create"} />}
+ variant={"ghost"}
+ size={"sm"}
+ {...props}
+ />
+ );
+};
+```
+
+### `DataList`
+
+**Constant** — imported from `webiny/admin/ui`
+
+```typescript
+import { DataList } from "webiny/admin/ui";
+```
+
+```typescript
+export const DataList = (propsInput: DataListProps) => {
+ let render: React.ReactNode | null;
+
+ const props = useMemo(() => {
+ return {
+ ...defaultDataListProps,
+ ...propsInput
+ };
+ }, [propsInput]);
+
+ if (props.loading) {
+ render = props.loader;
+ } else if (isEmpty(props.data)) {
+ render = props.noData;
+ } else {
+
+```
+
+### `DataListModal`
+
+**Constant** — imported from `webiny/admin/ui`
+
+```typescript
+import { DataListModal } from "webiny/admin/ui";
+```
+
+```typescript
+const DataListModal = withStaticProps(BaseDataListModal, {
+ Trigger: DataListModalTrigger,
+ Content: DataListModalContent
+});
+```
+
+### `DataListWithSections`
+
+**Constant** — imported from `webiny/admin/ui`
+
+```typescript
+import { DataListWithSections } from "webiny/admin/ui";
+```
+
+```typescript
+export const DataListWithSections = (propsInput: DataListProps) => {
+ let render: React.ReactNode | null;
+
+ const props = useMemo(() => {
+ return {
+ ...dataListWithSectionsDefaultProps,
+ ...propsInput
+ };
+ }, [propsInput]);
+
+ if (props.loading) {
+ render = props.loader;
+ } else if (isEmpty(props.data)) {
+ render = prop
+```
+
+### `DataTable`
+
+**Constant** — imported from `webiny/admin/ui`
+
+```typescript
+import { DataTable } from "webiny/admin/ui";
+```
+
+```typescript
+const DataTable = makeDecoratable("DataTable", DecoratableDataTable);
+```
+
+### `DelayedOnChange`
+
+**Constant** — imported from `webiny/admin/ui`
+
+```typescript
+import { DelayedOnChange } from "webiny/admin/ui";
+```
+
+```typescript
+export const DelayedOnChange = ({
+ children,
+ ...other
+}: DelayedOnChangeProps) => {
+ const firstMount = useRef(true);
+ const { onChange, delay = 400, value: initialValue } = other;
+ const [value, setValue] = useState(initialValue);
+ // Sync state and props
+ useEffect(() => {
+ // Do not update local state, if the incoming value
+```
+
+### `DeleteIcon`
+
+**Constant** — imported from `webiny/admin/ui`
+
+```typescript
+import { DeleteIcon } from "webiny/admin/ui";
+```
+
+```typescript
+export const DeleteIcon = (props: IconButtonProps) => {
+ return (
+ } label={"Delete"} />}
+ variant={"ghost"}
+ size={"sm"}
+ {...props}
+ />
+ );
+};
+```
+
+### `Dialog`
+
+**Constant** — imported from `webiny/admin/ui`
+
+```typescript
+import { Dialog } from "webiny/admin/ui";
+```
+
+```typescript
+const Dialog = withStaticProps(DecoratableDialog, {
+ ConfirmAction,
+ CancelAction,
+ Icon,
+ Close: DialogClose
+});
+```
+
+### `DownloadIcon`
+
+**Constant** — imported from `webiny/admin/ui`
+
+```typescript
+import { DownloadIcon } from "webiny/admin/ui";
+```
+
+```typescript
+export const DownloadIcon = (props: IconButtonProps) => {
+ return (
+ } label={"Download"} />}
+ variant={"ghost"}
+ size={"sm"}
+ {...props}
+ />
+ );
+};
+```
+
+### `Drawer`
+
+**Constant** — imported from `webiny/admin/ui`
+
+```typescript
+import { Drawer } from "webiny/admin/ui";
+```
+
+```typescript
+const Drawer = withStaticProps(DecoratableDrawer, {
+ ConfirmButton,
+ CancelButton,
+ Icon
+});
+```
+
+### `DropdownMenu`
+
+**Constant** — imported from `webiny/admin/ui`
+
+```typescript
+import { DropdownMenu } from "webiny/admin/ui";
+```
+
+```typescript
+const DropdownMenu = withStaticProps(DecoratableDropdownMenu, {
+ Separator: DropdownMenuSeparator,
+ Label: DropdownMenuLabel,
+ Group: DropdownMenuGroup,
+ Item: DropdownMenuItem,
+ Link: DropdownMenuLink,
+ CheckboxItem: DropdownMenuCheckboxItem
+});
+```
+
+### `DynamicFieldset`
+
+**Class** — imported from `webiny/admin/ui`
+
+```typescript
+import { DynamicFieldset } from "webiny/admin/ui";
+```
+
+```typescript
+class DynamicFieldset extends React.Component {
+ static defaultProps: Partial =;
+ header: React.ReactNode = null;
+ footer: React.ReactNode = null;
+ rows: React.ReactNode = null;
+ empty: React.ReactNode = null;
+ actions =;
+ removeData = (index: number) =>;
+ addData = (index = -1) =>;
+ renderHeader = (cb: () => React.ReactNode): React.ReactNode =>;
+ renderFooter = (cb: () => React.ReactNode): React.ReactNode =>;
+ renderRow = (cb: ChildrenRenderPropRowCallable): React.ReactNode =>;
+ renderEmpty = (cb: () => React.ReactNode): React.ReactNode =>;
+ public renderComponent(): React.ReactNode;
+ public override render();
+}
+```
+
+### `EditIcon`
+
+**Constant** — imported from `webiny/admin/ui`
+
+```typescript
+import { EditIcon } from "webiny/admin/ui";
+```
+
+```typescript
+export const EditIcon = (props: IconButtonProps) => {
+ return (
+ } label={"Edit"} />}
+ variant={"ghost"}
+ size={"sm"}
+ {...props}
+ />
+ );
+};
+```
+
+### `FilePicker`
+
+**Constant** — imported from `webiny/admin/ui`
+
+```typescript
+import { FilePicker } from "webiny/admin/ui";
+```
+
+```typescript
+const FilePicker = withStaticProps(DecoratableFilePicker, {
+ Preview: {
+ Image: ImagePreview,
+ RichItem: RichItemPreview,
+ TextOnly: TextOnlyPreview
+ }
+});
+```
+
+### `FilterIcon`
+
+**Constant** — imported from `webiny/admin/ui`
+
+```typescript
+import { FilterIcon } from "webiny/admin/ui";
+```
+
+```typescript
+export const FilterIcon = (props: IconButtonProps) => {
+ return (
+ } label={"Filter"} />}
+ variant={"ghost"}
+ size={"sm"}
+ {...props}
+ />
+ );
+};
+```
+
+### `Grid`
+
+**Constant** — imported from `webiny/admin/ui`
+
+```typescript
+import { Grid } from "webiny/admin/ui";
+```
+
+```typescript
+const Grid = withStaticProps(DecoratableGrid, { Column });
+```
+
+### `HeaderBar`
+
+**Constant** — imported from `webiny/admin/ui`
+
+```typescript
+import { HeaderBar } from "webiny/admin/ui";
+```
+
+```typescript
+const HeaderBar = makeDecoratable("HeaderBar", HeaderBarBase);
+```
+
+### `Heading`
+
+**Constant** — imported from `webiny/admin/ui`
+
+```typescript
+import { Heading } from "webiny/admin/ui";
+```
+
+```typescript
+const Heading = makeDecoratable("Heading", HeadingBase);
+```
+
+### `Icon`
+
+**Constant** — imported from `webiny/admin/ui`
+
+```typescript
+import { Icon } from "webiny/admin/ui";
+```
+
+```typescript
+const Icon = makeDecoratable("Icon", IconBase);
+```
+
+### `IconButton`
+
+**Constant** — imported from `webiny/admin/ui`
+
+```typescript
+import { IconButton } from "webiny/admin/ui";
+```
+
+```typescript
+const IconButton = makeDecoratable("IconButton", DecoratableIconButton);
+```
+
+### `IconPicker`
+
+**Constant** — imported from `webiny/admin/ui`
+
+```typescript
+import { IconPicker } from "webiny/admin/ui";
+```
+
+```typescript
+const IconPicker = makeDecoratable("IconPicker", DecoratableIconPicker);
+```
+
+### `Image`
+
+**Constant** — imported from `webiny/admin/ui`
+
+```typescript
+import { Image } from "webiny/admin/ui";
+```
+
+```typescript
+const Image = ({ ...rest }: ImageProps) => {
+ const finalProps = { ...rest };
+ const srcSet = finalProps.srcSet;
+ if (srcSet && typeof srcSet === "object") {
+ finalProps.srcSet = Object.keys(srcSet)
+ .map(key => `${srcSet[key]} ${key}`)
+ .join(", ");
+ }
+
+ return
;
+};
+```
+
+### `Input`
+
+**Constant** — imported from `webiny/admin/ui`
+
+```typescript
+import { Input } from "webiny/admin/ui";
+```
+
+```typescript
+const Input = makeDecoratable("Input", DecoratableInput);
+```
+
+### `Label`
+
+**Constant** — imported from `webiny/admin/ui`
+
+```typescript
+import { Label } from "webiny/admin/ui";
+```
+
+```typescript
+const Label = makeDecoratable("Label", LabelBase);
+```
+
+### `Link`
+
+**Constant** — imported from `webiny/admin/ui`
+
+```typescript
+import { Link } from "webiny/admin/ui";
+```
+
+```typescript
+export const Link = makeDecoratable("Link", LinkBase);
+```
+
+### `List`
+
+**Constant** — imported from `webiny/admin/ui`
+
+```typescript
+import { List } from "webiny/admin/ui";
+```
+
+```typescript
+const List = withStaticProps(makeDecoratable("List", DecoratableList), {
+ Item: ListItem
+});
+```
+
+### `ListIcon`
+
+**Constant** — imported from `webiny/admin/ui`
+
+```typescript
+import { ListIcon } from "webiny/admin/ui";
+```
+
+```typescript
+export const ListIcon = (props: IconButtonProps) => {
+ return (
+ } label={"List"} />}
+ variant={"ghost"}
+ size={"sm"}
+ {...props}
+ />
+ );
+};
+```
+
+### `Loader`
+
+**Constant** — imported from `webiny/admin/ui`
+
+```typescript
+import { Loader } from "webiny/admin/ui";
+```
+
+```typescript
+const Loader = makeDecoratable("Loader", DecoratableLoader);
+```
+
+### `LoginIcon`
+
+**Constant** — imported from `webiny/admin/ui`
+
+```typescript
+import { LoginIcon } from "webiny/admin/ui";
+```
+
+```typescript
+export const LoginIcon = (props: IconButtonProps) => {
+ return (
+ } label={"Login"} />}
+ variant={"ghost"}
+ size={"sm"}
+ {...props}
+ />
+ );
+};
+```
+
+### `MultiAutoComplete`
+
+**Constant** — imported from `webiny/admin/ui`
+
+```typescript
+import { MultiAutoComplete } from "webiny/admin/ui";
+```
+
+```typescript
+const MultiAutoComplete = makeDecoratable("MultiAutoComplete", DecoratableMultiAutoComplete);
+```
+
+### `MultiFilePicker`
+
+**Constant** — imported from `webiny/admin/ui`
+
+```typescript
+import { MultiFilePicker } from "webiny/admin/ui";
+```
+
+```typescript
+const MultiFilePicker = withStaticProps(DecoratableMultiFilePicker, {
+ Preview: {
+ Image: ImagePreview,
+ RichItem: RichItemPreview,
+ TextOnly: TextOnlyPreview
+ }
+});
+```
+
+### `NextPageIcon`
+
+**Constant** — imported from `webiny/admin/ui`
+
+```typescript
+import { NextPageIcon } from "webiny/admin/ui";
+```
+
+```typescript
+export const NextPageIcon = (props: IconButtonProps) => {
+ return (
+ } label={"Next Page"} />}
+ variant={"ghost"}
+ size={"sm"}
+ {...props}
+ />
+ );
+};
+```
+
+### `OptionsIcon`
+
+**Constant** — imported from `webiny/admin/ui`
+
+```typescript
+import { OptionsIcon } from "webiny/admin/ui";
+```
+
+```typescript
+export const OptionsIcon = (props: IconButtonProps) => {
+ return (
+ } label={"Options"} />}
+ variant={"ghost"}
+ size={"sm"}
+ {...props}
+ />
+ );
+};
+```
+
+### `OverlayLoader`
+
+**Constant** — imported from `webiny/admin/ui`
+
+```typescript
+import { OverlayLoader } from "webiny/admin/ui";
+```
+
+```typescript
+const OverlayLoader = makeDecoratable("OverlayLoader", DecoratableOverlayLoader);
+```
+
+### `Popover`
+
+**Constant** — imported from `webiny/admin/ui`
+
+```typescript
+import { Popover } from "webiny/admin/ui";
+```
+
+```typescript
+const Popover = makeDecoratable("Popover", DecoratablePopover);
+```
+
+### `Portal`
+
+**Constant** — imported from `webiny/admin/ui`
+
+```typescript
+import { Portal } from "webiny/admin/ui";
+```
+
+```typescript
+const Portal = PortalPrimitive.Root;
+```
+
+### `PreviousPageIcon`
+
+**Constant** — imported from `webiny/admin/ui`
+
+```typescript
+import { PreviousPageIcon } from "webiny/admin/ui";
+```
+
+```typescript
+export const PreviousPageIcon = (props: IconButtonProps) => {
+ return (
+ } label={"Previous Page"} />}
+ variant={"ghost"}
+ size={"sm"}
+ {...props}
+ />
+ );
+};
+```
+
+### `ProgressBar`
+
+**Constant** — imported from `webiny/admin/ui`
+
+```typescript
+import { ProgressBar } from "webiny/admin/ui";
+```
+
+```typescript
+const ProgressBar = makeDecoratable("ProgressBar", DecoratableProgressBar);
+```
+
+### `Radio`
+
+**Constant** — imported from `webiny/admin/ui`
+
+```typescript
+import { Radio } from "webiny/admin/ui";
+```
+
+```typescript
+const Radio = makeDecoratable("Radio", DecoratableRadio);
+```
+
+### `RadioGroup`
+
+**Constant** — imported from `webiny/admin/ui`
+
+```typescript
+import { RadioGroup } from "webiny/admin/ui";
+```
+
+```typescript
+const RadioGroup = makeDecoratable("RadioGroup", DecoratableRadioGroup);
+```
+
+### `RangeSlider`
+
+**Constant** — imported from `webiny/admin/ui`
+
+```typescript
+import { RangeSlider } from "webiny/admin/ui";
+```
+
+```typescript
+const RangeSlider = makeDecoratable("RangeSlider", DecoratableRangeSlider);
+```
+
+### `RefreshIcon`
+
+**Constant** — imported from `webiny/admin/ui`
+
+```typescript
+import { RefreshIcon } from "webiny/admin/ui";
+```
+
+```typescript
+export const RefreshIcon = (props: IconButtonProps) => {
+ return (
+ } label={"Refresh"} />}
+ variant={"ghost"}
+ size={"sm"}
+ {...props}
+ />
+ );
+};
+```
+
+### `ScrollArea`
+
+**Function** — imported from `webiny/admin/ui`
+
+```typescript
+import { ScrollArea } from "webiny/admin/ui";
+```
+
+```typescript
+function ScrollArea(
+```
+
+### `Scrollbar`
+
+**Constant** — imported from `webiny/admin/ui`
+
+```typescript
+import { Scrollbar } from "webiny/admin/ui";
+```
+
+```typescript
+const Scrollbar = (props: ScrollbarProps) => {
+ return ;
+};
+```
+
+### `ScrollBar`
+
+**Function** — imported from `webiny/admin/ui`
+
+```typescript
+import { ScrollBar } from "webiny/admin/ui";
+```
+
+```typescript
+function ScrollBar(
+```
+
+### `SegmentedControl`
+
+**Constant** — imported from `webiny/admin/ui`
+
+```typescript
+import { SegmentedControl } from "webiny/admin/ui";
+```
+
+```typescript
+const SegmentedControl = makeDecoratable("SegmentedControl", DecoratableSegmentedControl);
+```
+
+### `Select`
+
+**Constant** — imported from `webiny/admin/ui`
+
+```typescript
+import { Select } from "webiny/admin/ui";
+```
+
+```typescript
+const Select = makeDecoratable("Select", DecoratableSelect);
+```
+
+### `Separator`
+
+**Constant** — imported from `webiny/admin/ui`
+
+```typescript
+import { Separator } from "webiny/admin/ui";
+```
+
+```typescript
+const Separator = makeDecoratable("Separator", SeparatorBase);
+```
+
+### `Sidebar`
+
+**Constant** — imported from `webiny/admin/ui`
+
+```typescript
+import { Sidebar } from "webiny/admin/ui";
+```
+
+```typescript
+const Sidebar = withStaticProps(DecoratableSidebar, {
+ Item: SidebarMenuItem,
+ Link: SidebarMenuLink,
+ Group: SidebarMenuGroup,
+ Icon: SidebarIcon
+});
+```
+
+### `SidebarProvider`
+
+**Constant** — imported from `webiny/admin/ui`
+
+```typescript
+import { SidebarProvider } from "webiny/admin/ui";
+```
+
+```typescript
+const SidebarProvider = ({
+ className,
+ children,
+ state: cachedState,
+ onChangeState,
+ ...props
+}: SidebarProviderProps) => {
+ const [sidebarState, setSidebarState] = React.useState(() =>
+ createInitialSidebarState(cachedState)
+ );
+ const [pinnedItemsData, setPinnedItemsData] = React.useState