Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
84 changes: 84 additions & 0 deletions docs/developer-docs/6.x/admin/file-url-formatter.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
---
id: a3f8kd92
title: File URL Formatter
description: Learn how to customize file and image URLs in the Webiny admin app using the FileUrlFormatter extension point.
---

import { Alert } from "@/components/Alert";
import fileUrlFormatter from "./assets/file-url-formatter.png";

<Alert type="success" title="WHAT YOU'LL LEARN">

- what the FileUrlFormatter extension point is and where it applies
- how to implement and register a custom file URL formatter
- how to remap query parameters for your own CDN or image service

</Alert>

## Overview

<Alert type="info">

This extension point is most relevant if you are replacing Webiny's built-in File Manager with your own Digital Asset Manager (DAM). If you are using the default File Manager, no configuration is needed.

</Alert>

File URLs for images displayed in the Admin app pass through the `FileUrlFormatter` extension point before being rendered.

You can customize how those URLs are constructed: remap parameters to your CDN's own syntax, add authentication tokens, rewrite the host, or apply any other transformation your image delivery pipeline requires. For example, `FilePicker` calls `format(url, { width: 128 })` when rendering thumbnails — a custom formatter can intercept that and swap the standard `?width=N` for whatever your CDN expects.

<Alert type="info">

Only one `FileUrlFormatter` is active at a time. When you register your own implementation it replaces the File Manager default — the last implementation registered wins.

</Alert>

## Implement the Formatter

Create an implementation of `FileUrlFormatter`. The `url` object is mutable — modify it in place. `params.width` is the only supported parameter.

```typescript extensions/fileUrlFormatter/MyFileUrlFormatter.ts
import { FileUrlFormatter } from "webiny/admin/file-manager";

class MyFileUrlFormatter implements FileUrlFormatter.Interface {
format(url: URL, params?: FileUrlFormatter.Params): void {
if (params?.width !== undefined) {
url.searchParams.set("my_width", String(params.width));
}
}
}

export const MyFileUrlFormatterImpl = FileUrlFormatter.createImplementation({
implementation: MyFileUrlFormatter,
dependencies: []
});
```

## Register the Formatter

Wrap the implementation in a feature and mount it with `RegisterFeature`:

```tsx extensions/fileUrlFormatter/index.tsx
import React from "react";
import { createFeature, RegisterFeature } from "webiny/admin";
import { MyFileUrlFormatterImpl } from "./MyFileUrlFormatter.js";

const FileUrlFormatterFeature = createFeature({
name: "MyApp/FileUrlFormatter",
register(container) {
container.register(MyFileUrlFormatterImpl).inSingletonScope();
}
});

export default () => <RegisterFeature feature={FileUrlFormatterFeature} />;
```

Then add the extension to your `webiny.config.tsx`:

```tsx webiny.config.tsx
<Admin.Extension src={"@/extensions/fileUrlFormatter/index.tsx"} />
```

With the extension registered, file thumbnails in the Admin app will use your formatter. Here is the result:

<Image src={fileUrlFormatter} alt="File URL Formatter result" />
2 changes: 2 additions & 0 deletions docs/developer-docs/6.x/navigation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ export const Navigation = ({ children }: { children: React.ReactNode }) => {
<Page link={"admin/whitelabeling"} />
<Page link={"admin/connect-custom-domain"} />
<Page link={"admin/build-params"} />
<Page link={"admin/file-url-formatter"} />
</Group>
<Group
title={"API"}
Expand Down Expand Up @@ -125,6 +126,7 @@ export const Navigation = ({ children }: { children: React.ReactNode }) => {
title={"Customize Page List Columns"}
/>
<Page link={"website-builder/event-handlers"} title={"Event Handlers"} />
<Page link={"website-builder/preview-url-modifier"} title={"Preview URL Modifier"} />
</Group>
<Group
title={"Tenant Manager"}
Expand Down
13 changes: 13 additions & 0 deletions docs/developer-docs/6.x/reference/extensions/infra.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,19 @@ Adds a fully custom Lambda function to the API application, with both an applica
| `functionSrc` | `string` | Yes | Path to the Lambda handler source file |
| `pulumiSrc` | `string` | Yes | Path to the Pulumi infrastructure file (must follow `ApiPulumi` abstraction) |

### Infra.Api.MaxBundleSize

Sets the maximum allowed size of the backend (AWS Lambda) function code. If the built output exceeds this limit, the build fails immediately. The default is **4.5 MB**.

| Prop | Type | Required | Description |
| ------ | -------- | -------- | ----------------------------- |
| `size` | `number` | Yes | Maximum bundle size in bytes. |

```tsx
{/* Raise the API bundle size limit to 6 MB */}
<Infra.Api.MaxBundleSize size={6 * 1024 * 1024} />
```

### Infra.Api.StackOutputValue

Adds a custom key-value entry to the API Pulumi stack outputs. Can be used multiple times.
Expand Down
109 changes: 109 additions & 0 deletions docs/developer-docs/6.x/website-builder/preview-url-modifier.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
---
id: m4x7pq2n
title: Preview URL Modifier
description: Learn how to inject custom query parameters into Website Builder's live preview URLs.
---

import { Alert } from "@/components/Alert";

<Alert type="success" title="WHAT YOU'LL LEARN">

- what the PreviewUrlModifier extension point is and where it applies
- how to implement and register a custom preview URL modifier
- how to use async operations (e.g. fetching a signed token) inside a modifier

</Alert>

## Overview

Every live preview URL that Website Builder generates — in the page editor iframe, the address bar's copy link button, and the pages list — can be customized via the `PreviewUrlModifier` extension point.

When registered, the modifier receives the fully-constructed `URL` object just before it is used. You can add, remove, or change any query parameter, including ones fetched asynchronously from a remote API.

<Alert type="info">

Only one `PreviewUrlModifier` can be registered per project. Avoid setting parameters that start with `wb.` — those are reserved for internal Website Builder use.

</Alert>

## Implement the Modifier

Create a class that implements `PreviewUrlModifier.Interface`. The single required method is `modify(url: URL): Promise<void>`. Mutate the `url` object in place — the return value is ignored.

```typescript extensions/previewUrlModifier/MyPreviewUrlModifier.ts
import { PreviewUrlModifier } from "webiny/admin/website-builder";

class MyPreviewUrlModifier implements PreviewUrlModifier.Interface {
async modify(url: URL) {
url.searchParams.set("my-param", "my-value");
}
}

export default PreviewUrlModifier.createImplementation({
implementation: MyPreviewUrlModifier,
dependencies: []
});
```

### Async Example — Fetching a Signed Token

Mark the method `async` to perform any async work before the URL is handed back:

```typescript extensions/previewUrlModifier/MyPreviewUrlModifier.ts
import { PreviewUrlModifier } from "webiny/admin/website-builder";

class MyPreviewUrlModifier implements PreviewUrlModifier.Interface {
async modify(url: URL) {
const token = await fetch("/api/preview-token").then(r => r.text());
url.searchParams.set("token", token);
}
}

export default PreviewUrlModifier.createImplementation({
implementation: MyPreviewUrlModifier,
dependencies: []
});
```

## Register the Feature

Wire the implementation into the DI container using `createFeature` and `RegisterFeature`:

```tsx extensions/previewUrlModifier/index.tsx
import React from "react";
import { createFeature, RegisterFeature } from "webiny/admin";
import MyPreviewUrlModifier from "./MyPreviewUrlModifier.js";

const PreviewUrlModifierFeature = createFeature({
name: "MyApp/PreviewUrlModifier",
register(container) {
container.register(MyPreviewUrlModifier);
}
});

export default () => <RegisterFeature feature={PreviewUrlModifierFeature} />;
```

Then register the extension in `webiny.config.tsx`:

```tsx webiny.config.tsx
import React from "react";
import { Admin } from "webiny/extensions";

export const Extensions = () => {
return (
<>
{/* ... other extensions */}
<Admin.Extension src={"@/extensions/previewUrlModifier/index.tsx"} />
</>
);
};
```

## Where the Modifier Applies

| Surface | Description |
|---|---|
| Editor iframe | The live-editing iframe in the page editor |
| Address bar link | The "copy preview link" button in the editor toolbar |
| Pages list | Preview icon links in the pages list table |
8 changes: 8 additions & 0 deletions docs/release-notes/6.4.0/changelog.ai.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
AI Context: 6.4.0 Changelog (changelog.mdx)

This file tracks manual edits made after the generation script ran.
The script reads the "Skipped PRs" section to avoid re-adding removed entries.

## Skipped PRs

## Manual Rewrites
Loading