Field Methods

Resolve blocks, layouts, and permalinks for headless content delivery.

Kirby Headless provides field methods to resolve UUIDs and enhance block and layout fields for headless usage.

toResolvedBlocks()

The toResolvedBlocks() method extends Kirby's toBlocks() method by resolving UUIDs to file and page objects. This eliminates the need to resolve UUIDs in your frontend application.

Before and After

Using Kirby's default toBlocks() method returns UUIDs:

{
  "content": {
    "image": ["file://BYXR0pvumEbfTknP"],
    "alt": "Staring at stars"
  },
  "id": "a1c0f653-2e36-4b07-a7fa-d22ef27dd114",
  "isHidden": false,
  "type": "image"
}

Using toResolvedBlocks() resolves UUIDs to complete file objects:

{
  "content": {
    "alt": "Staring at stars",
    "image": [
      {
        "url": "http://example.com/media/pages/notes/image.jpg",
        "width": 1024,
        "height": 683
      }
    ]
  },
  "id": "a1c0f653-2e36-4b07-a7fa-d22ef27dd114",
  "isHidden": false,
  "type": "image"
}

Files Resolver

Configure which file fields to resolve in your blocks:

config.php
return [
    'blocksResolver' => [
        'files' => [
            // Resolve the `image` field in the `gallery` block
            'gallery' => ['image'],
            // Resolve multiple fields
            'hero' => ['background', 'thumbnail']
        ]
    ]
];

The default file resolver returns:

config.php
return [
    'blocksResolver' => [
        'defaultResolvers' => [
            'files' => fn (\Kirby\Cms\File $file) => [
                'url' => $file->url(),
                'width' => $file->width(),
                'height' => $file->height(),
                'srcset' => $file->srcset(),
                'alt' => $file->alt()->value()
            ]
        ]
    ]
];

Override the default resolver to customize the output:

config.php
return [
    'blocksResolver' => [
        'defaultResolvers' => [
            'files' => fn (\Kirby\Cms\File $file) => [
                'url' => $file->url(),
                'alt' => $file->alt()->value()
            ]
        ]
    ]
];

Pages Resolver

Configure which page fields to resolve in your blocks:

config.php
return [
    'blocksResolver' => [
        'pages' => [
            // Resolve the `link` field in the `cta` block
            'cta' => ['link'],
            // Resolve multiple fields
            'references' => ['related', 'author']
        ]
    ]
];

The default page resolver returns:

config.php
return [
    'blocksResolver' => [
        'defaultResolvers' => [
            'pages' => fn (\Kirby\Cms\Page $page) => [
                'uri' => $page->uri(),
                'title' => $page->title()->value()
            ]
        ]
    ]
];

Custom Resolvers

Define custom resolvers for specific fields in specific blocks using the {blockName}:{fieldName} syntax:

config.php
use Kirby\Cms\Block;
use Kirby\Content\Field;

return [
    'blocksResolver' => [
        'resolvers' => [
            // Resolve the `link` field in the `intro` block
            'intro:link' => fn (Field $field, Block $block) => [
                'value' => $field->value(),
                'uri' => $field->toPage()?->uri()
            ],
            // Resolve KirbyText in the `text` field of the `note` block
            'note:text' => fn (Field $field, Block $block) =>
                $field->kirbytext()->value(),
            // Resolve structure field
            'testimonial:author' => fn (Field $field, Block $block) =>
                $field->toStructure()->first()?->toArray()
        ]
    ]
];

Resolved Key

By default, resolved fields replace the original field values. To keep both original and resolved values, configure a resolvedKey:

config.php
return [
    'blocksResolver' => [
        'resolvedKey' => 'resolved'
    ]
];

This stores resolved content in a separate key:

{
  "content": {
    "alt": "Staring at stars",
    "image": ["file://BYXR0pvumEbfTknP"],
    "resolved": {
      "image": {
        "url": "http://example.com/media/pages/notes/image.jpg",
        "width": 1024,
        "height": 683
      }
    }
  },
  "id": "a1c0f653-2e36-4b07-a7fa-d22ef27dd114",
  "isHidden": false,
  "type": "image"
}

toResolvedLayouts()

The toResolvedLayouts() method extends Kirby's toLayouts() method. It uses toResolvedBlocks() under the hood, so all block resolver configurations apply.

site/templates/default.php
<?php

$data = [
    'title' => $page->title()->value(),
    'layout' => $page->layout()->toResolvedLayouts()->toArray()
];

echo \Kirby\Data\Json::encode($data);

The resolvePermalinks() method resolves page and file permalinks in href and src attributes. This is useful for writer fields containing permalink URLs like /@/page/nDvVIAwDBph4uOpm.

This method works the same as Kirby's built-in permalinksToUrls() method, but supports a custom URL parser.

Basic Usage

use Kirby\Cms\Page;

return [
    'query' => 'page("home")',
    'select' => [
        'title' => true,
        'text' => fn (Page $page) => $page->text()->resolvePermalinks()
    ]
];

Custom URL Parser

For headless setups, you may want to remove the origin or language prefix from URLs:

config.php
return [
    'permalinksResolver' => [
        // Strip the origin from URLs
        'urlParser' => function (string $url, \Kirby\Cms\App $kirby) {
            return parse_url($url, PHP_URL_PATH);
        }
    ]
];

For multi-language sites, remove language prefixes:

config.php
return [
    'permalinksResolver' => [
        'urlParser' => function (string $url, \Kirby\Cms\App $kirby) {
            $path = parse_url($url, PHP_URL_PATH);

            // Strip language prefix for German URLs
            if (str_starts_with($path, '/de')) {
                return substr($path, 3);
            }

            return $path;
        }
    ]
];