diff --git a/code_samples/page/pagefield_layout.html.twig b/code_samples/page/pagefield_layout.html.twig
new file mode 100644
index 0000000000..0eacab3fc5
--- /dev/null
+++ b/code_samples/page/pagefield_layout.html.twig
@@ -0,0 +1,22 @@
+
+ {# The required attribute for the displayed zone #}
+
+ {# If a zone with [0] index contains any blocks #}
+ {% if zones[0].blocks %}
+ {# for each block #}
+ {% for block in blocks %}
+ {# create a new layer with appropriate ID #}
+
+ {# render the block by using the "Ibexa\\Bundle\\FieldTypePage\\Controller\\BlockController::renderAction" controller #}
+ {# location.id is the ID of the Location of the current content item, block.id is the ID of the current block #}
+ {{ render_esi(controller('Ibexa\\Bundle\\FieldTypePage\\Controller\\BlockController::renderAction', {
+ 'locationId': locationId,
+ 'blockId': block.id,
+ 'versionNo': versionInfo.versionNo,
+ 'languageCode': field.languageCode
+ }, ibexa_append_cacheable_query_params(block))) }}
+
+ {% endfor %}
+ {% endif %}
+
+
diff --git a/docs/content_management/field_types/field_type_reference/pagefield.md b/docs/content_management/field_types/field_type_reference/pagefield.md
index d5b0977f76..b8497dc0d2 100644
--- a/docs/content_management/field_types/field_type_reference/pagefield.md
+++ b/docs/content_management/field_types/field_type_reference/pagefield.md
@@ -41,7 +41,7 @@ You can access them using twig (for example, `{{ zones[0].id }}` ).
Each div that's a zone should have the `data-ibexa-zone-id` attribute with zone ID as a value for a zone container.
-To render a block inside the layout, use the Twig `render_esi()` function to call `Ibexa\\Bundle\\FieldTypePage\\Controller\\BlockController::renderAction`.
+To render a block inside the layout, use the Twig [`render_esi()`]([[= symfony_doc =]]/reference/twig_reference.html#render-esi) function to call `Ibexa\\Bundle\\FieldTypePage\\Controller\\BlockController::renderAction`.
The `renderAction` has the following parameters:
@@ -52,6 +52,10 @@ The `renderAction` has the following parameters:
| `versionNo` | Version number of the content item to render. |
| `languageCode` | Language code of the content item to render. |
+If your block needs to be dependent on query parameters like "page" and you already configured your custom block with a [`cacheable_query_params configuration`](page_blocks.md#block-configuration), pass [`ibexa_append_cacheable_query_params(block)`](page_twig_functions.md#ibexa_append_cacheable_query_params) as the third argument to the [`controller()` Twig function]([[= symfony_doc =]]/reference/twig_reference.html#controller) so that the HTTP cache can vary based on those query parameters.
+
+In a fresh installation, the feature is only used by the back office's [Dashboard blocks]([[= user_doc =]]/getting_started/dashboard/dashboard_block_reference/): "My content" and "Review queue".
+
Example usage:
``` html+twig
@@ -60,32 +64,11 @@ Example usage:
'blockId': block.id,
'versionNo': versionInfo.versionNo,
'languageCode': field.languageCode
-})) }}
+}, ibexa_append_cacheable_query_params(block))) }}
```
As a whole a sample layout could look as follows:
``` html+twig
-
- {# The required attribute for the displayed zone #}
-
- {# If a zone with [0] index contains any blocks #}
- {% if zones[0].blocks %}
- {# for each block #}
- {% for block in blocks %}
- {# create a new layer with appropriate ID #}
-
- {# render the block by using the "Ibexa\\Bundle\\FieldTypePage\\Controller\\BlockController::renderAction" controller #}
- {# location.id is the ID of the Location of the current content item, block.id is the ID of the current block #}
- {{ render_esi(controller('Ibexa\\Bundle\\FieldTypePage\\Controller\\BlockController::renderAction', {
- 'locationId': locationId,
- 'blockId': block.id,
- 'versionNo': versionInfo.versionNo,
- 'languageCode': field.languageCode
- })) }}
-
- {% endfor %}
- {% endif %}
-
-
+[[= include_file('code_samples/page/pagefield_layout.html.twig') =]]
```
diff --git a/docs/content_management/pages/page_blocks.md b/docs/content_management/pages/page_blocks.md
index d265601a33..e85ffaf535 100644
--- a/docs/content_management/pages/page_blocks.md
+++ b/docs/content_management/pages/page_blocks.md
@@ -18,15 +18,16 @@ For information on how to create and configure new layouts for the Page, see [Pa
Each configured block has an identifier and the following settings:
-| Setting | Description |
-|--------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------|
-| `name` | Name of the block used in the Page Builder interface. Translatable using the `ibexa_page_fieldtype` translation domain. |
-| `category` | Category in the Page Builder **Page blocks** toolbox that the block is shown in. Translatable using the `ibexa_page_fieldtype` translation domain. |
-| `thumbnail` | Thumbnail used in the Page Builder **Page blocks** toolbox. |
-| `views` | Available [templates for the block](#block-templates). |
-| `visible` | (Optional) Toggles the block's visibility in the Page Builder **Page blocks** toolbox. Remove the block from the layout before you publish another version of the page. |
-| `configuration_template` | (Optional) Template for the block settings modal. |
-| `attributes` | (Optional) List of [block attributes](page_block_attributes.md). |
+| Setting | Description |
+|---------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| `name` | Name of the block used in the Page Builder interface. Translatable using the `ibexa_page_fieldtype` translation domain. |
+| `category` | Category in the Page Builder **Page blocks** toolbox that the block is shown in. Translatable using the `ibexa_page_fieldtype` translation domain. |
+| `thumbnail` | Thumbnail used in the Page Builder **Page blocks** toolbox. |
+| `views` | Available [templates for the block](#block-templates). |
+| `visible` | (Optional) Toggles the block's visibility in the Page Builder **Page blocks** toolbox. Remove the block from the layout before you publish another version of the page. |
+| `configuration_template` | (Optional) Template for the block settings modal. |
+| `attributes` | (Optional) List of [block attributes](page_block_attributes.md). |
+| `cacheable_query_params` | (Optional) List of query parameters the block's [ESI HTTP cache](http_cache_configuration.md#when-to-use-esi) varies on.
For example, if the block is paginated using `?page=ℕ` from the page URL, add `page` to this list.
See [`ibexa_append_cacheable_query_params()`Twig function](page_twig_functions.md#ibexa_append_cacheable_query_params). |
For example:
diff --git a/docs/infrastructure_and_maintenance/cache/http_cache/http_cache_configuration.md b/docs/infrastructure_and_maintenance/cache/http_cache/http_cache_configuration.md
index 02e0e99348..44373504cd 100644
--- a/docs/infrastructure_and_maintenance/cache/http_cache/http_cache_configuration.md
+++ b/docs/infrastructure_and_maintenance/cache/http_cache/http_cache_configuration.md
@@ -92,4 +92,4 @@ You should not use ESI for parts that are effectively uncached, because your rev
!!! note "ESI limitations with the URIElement SiteAccess matcher"
- Is isn't possible to share ESIs across the SiteAccesses when using URI matching as URI contains the SiteAccess name encoded in its path information.
+ It isn't possible to share ESIs across the SiteAccesses when using URI matching as URI contains the SiteAccess name encoded in its path information.
diff --git a/docs/release_notes/ibexa_dxp_v5.0.md b/docs/release_notes/ibexa_dxp_v5.0.md
index 074b312180..7dd3677eb3 100644
--- a/docs/release_notes/ibexa_dxp_v5.0.md
+++ b/docs/release_notes/ibexa_dxp_v5.0.md
@@ -10,6 +10,35 @@ month_change: false
+[[% set version = 'v5.0.X' %]]
+
+[[= release_note_entry_begin("Ibexa DXP " + version, 'YYYY-MM-DD', ['Experience', 'Commerce']) =]]
+
+### Improved HTTP caching for Page Builder and dashboard blocks
+
+You can now indicate which [query parameters](https://en.wikipedia.org/wiki/Query_string) must be used as keys when generating [HTTP cache](http_cache.md) for block requests.
+
+This allows you to improve performance for blocks by utilizing HTTP cache more effectively, for example, for paginated blocks in the [dashboard](customize_dashboard.md).
+
+To set it up, use the new `cacheable_query_params` [block setting](page_blocks.md#block-configuration).
+
+Then, adjust your [layouts](render_page.md#configure-layout) and pass the parameters to [Symfony's `controller function`]([[= symfony_doc =]]/reference/twig_reference.html#controller) by using the new `ibexa_append_cacheable_query_params` Twig function, as in the example below:
+
+``` html+twig
+{{ render_esi(controller('Ibexa\\Bundle\\FieldTypePage\\Controller\\BlockController::renderAction',
+ {
+ 'locationId': locationId,
+ 'contentId': contentInfo.id,
+ 'blockId': block.id,
+ 'versionNo': versionInfo.versionNo,
+ 'languageCode': field.languageCode
+ },
+ ibexa_append_cacheable_query_params(block)
+)) }}
+```
+
+[[= release_note_entry_end() =]]
+
[[% set version = 'v5.0.5' %]]
[[= release_note_entry_begin("Ibexa DXP " + version, '2026-01-15', ['Headless', 'Experience', 'Commerce']) =]]
diff --git a/docs/templating/twig_function_reference/page_twig_functions.md b/docs/templating/twig_function_reference/page_twig_functions.md
new file mode 100644
index 0000000000..056d9b1e4a
--- /dev/null
+++ b/docs/templating/twig_function_reference/page_twig_functions.md
@@ -0,0 +1,33 @@
+---
+description: Page field and page block Twig functions provide access to configuration.
+page_type: reference
+edition: experience
+month_change: true
+---
+
+# Page Twig functions
+
+## `ibexa_append_cacheable_query_params()`
+
+Get the query parameters of a page block as [configured in `cacheable_query_params`](page_blocks.md#block-configuration).
+If the block type has no configured query parameters, an empty array is returned.
+
+```twig
+{{ render_esi(controller('Ibexa\\Bundle\\FieldTypePage\\Controller\\BlockController::renderAction', {
+ 'locationId': locationId,
+ 'blockId': block.id,
+ 'versionNo': versionInfo.versionNo,
+ 'languageCode': field.languageCode
+}, ibexa_append_cacheable_query_params(block))) }}
+```
+
+## `ibexa_page_layout()`
+
+Get the layout template of a landing page.
+
+```twig
+{% include ibexa_page_layout(page) with {'zones': page.zones} %}
+```
+
+It can be used to render a [page field](pagefield.md).
+For an example, you can look at how the default `vendor/ibexa/fieldtype-page/src/bundle/Resources/views/fields/ibexa_landing_page.html.twig` uses it.
diff --git a/docs/templating/twig_function_reference/twig_function_reference.md b/docs/templating/twig_function_reference/twig_function_reference.md
index abba7c79b3..c9810c8e80 100644
--- a/docs/templating/twig_function_reference/twig_function_reference.md
+++ b/docs/templating/twig_function_reference/twig_function_reference.md
@@ -14,6 +14,7 @@ In addition to the [native functions provided by Twig](https://twig.symfony.com/
"templating/twig_function_reference/content_twig_functions",
"templating/twig_function_reference/component_twig_functions",
"templating/twig_function_reference/field_twig_functions",
+ "templating/twig_function_reference/page_twig_functions",
"templating/twig_function_reference/product_twig_functions",
"templating/twig_function_reference/site_context_twig_functions",
"templating/twig_function_reference/storefront_twig_functions",
diff --git a/mkdocs.yml b/mkdocs.yml
index 88a2409448..6a03ccc23d 100644
--- a/mkdocs.yml
+++ b/mkdocs.yml
@@ -311,6 +311,7 @@ nav:
- Content Twig functions: templating/twig_function_reference/content_twig_functions.md
- Date Twig filters: templating/twig_function_reference/date_twig_filters.md
- Field Twig functions: templating/twig_function_reference/field_twig_functions.md
+ - Page Twig functions: templating/twig_function_reference/page_twig_functions.md
- Icon Twig functions: templating/twig_function_reference/icon_twig_functions.md
- Image Twig functions: templating/twig_function_reference/image_twig_functions.md
- Product Twig functions: templating/twig_function_reference/product_twig_functions.md