Skip to content

Kirby 3.7.5

Beyond Kirby

Decoupling responsibilities

Like many other CMSs, Kirby has a backend part (the Panel and the file system) where your data is stored and managed, and a frontend part (templates, snippets, controllers) that is responsible for getting the data from the backend and presenting it to the website visitors.

This combination is perfectly fine for most website projects.

However, if you have use cases where you…

  • Want to feed multiple channels (mobile apps, smart devices, print products...) from a single source of truth
  • Want to use progressive enhancement to make your web frontend more interactive and dynamic
  • Want to use static site generators
  • etc.

…then you can decouple the data processing and storage of your CMS backend from your frontend. You basically cut off the head, hence the buzzword "headless CMS". Your CMS backend and your decoupled frontend communicate via an API, usually providing JSON data.

Approaches for "headless" Kirby

With Kirby, you have several options to run in "headless" mode.

  1. Content representations
  2. Kirby's REST API
  3. The KQL plugin
  4. Custom routes

The following is an introduction to each of these options and an overview of their uses.

The technologies and approaches we describe here have very valid uses as we showed above.

Sometimes, however, "headless" technologies are used for their own sake, for example to satisfy a buzzword-driven project requirement or to reduce the (perceived) development effort. This is often at the cost of performance (due to additional requests, JS code and frontend calculations), accessibility (due to issues with semantics), efficiency (due to a higher energy usage) and therefore at the cost of the overall user experience.

Content representations

Content representations work like standard Kirby templates and are usually bound to a page type. They are a great way to create an API that provides exactly the data you need.

By default, content representations are publicly accessible, so they're great for content that is only accessed via GET requests. However, you can of course add authentication if needed or lock your API server-side to prevent unauthorized access.

As the JSON templates are custom-built by you, they are by design customized to your specific use case. This can be both an advantage and a downside:

  • With complete control over the output, the attack surface is limited and data leaks can be effectively prevented.
  • Also the performance is as good as it gets – because only the needed data is returned.
  • However, each template needs to be developed before the data can be used. This means extra effort on the backend side and requires adaptation if the set of data that's needed by the client changes in the future.

When to use

  • You want an easy-to-implement way to get data from Kirby without having to worry about authentication
  • You want full control over the output
  • You don't mind the extra effort



The REST API was originally designed for use with the Panel (and is of course tailored for that purpose), but it can also be used by you and even extended. However, REST has the problem that it is very limited compared to the flexibility we usually have in Kirby.

The REST API is great for getting a set of data like a list of users or pages. It's also great when you need to change data with CRUD operations: create pages, delete pages, add files, etc., and that's what we're mainly using it for right now.

Every request to the REST API requires authentication. For remote requests from another site Kirby supports HTTP Basic Auth, for authentication from the same site or domain you can use session-based authentication.

You can extend the REST API with your own custom endpoints which means great flexibility. Your custom endpoints are automatically protected with the same authentication layer as the default endpoints.

It is not recommended to use HTTP Basic Auth in combination with JavaScript front-ends, as you will be exposing your credentials. While there are examples in the wild that implement this via a Panel user with no privileges, this is not the way Basic Auth should be used. By exposing credentials, authentication no longer has a purpose as the access is public.

When to use

Using the REST API is the way to go if you want to modify data.



With KQL, you don't need to write backend code. Your frontend can retrieve the data you need without any changes to the backend. This brings a lot of flexibility and you hardly need to leave your frontend code. For authentication, the same methods are used as for the REST API. In addition, a mode without authentication is supported. KQL supports only a subset of Kirby's API, i.e. non-destructive commands.

KQL allows you to fully customize results to your application needs.

KQL allows access to all content of your Kirby site. Before you disable authentication, please ensure that all and every piece of your site's content is public. Sensitive data may include (but not be limited to) form submissions, drafts, user data etc.

When to use

  • You want to leverage Kirby's API, but without the hassle
  • You do not need to modify any data


KQL Readme
KQL Playground

Custom routes

For completeness sake, let's not forget routes. Routes could also be an option for simple data models, e.g. for use cases where you want to provide a limited set of data from a single endpoint. This approach probably works best if you use Kirby as a standard CMS but want to re-use some data for other purposes.


Where to go from here

As we have seen, Kirby gives you the freedom of choice when it comes to operating in headless mode. Each of the methods presented has its advantages and disadvantages, and which of the options is best for you will largely depend on your specific requirements.

The different methods can even be combined, or you can use headless mode in addition to the traditional approach with Kirby as a full CMS.

Here are a few more resources that can help you get started or give you more ideas for implementing your own solutions. We will update this list on an ongoing basis.