JavaScript Data

JavaScript data is useful if you want to pass data for every view from PHP to JS.

Usage

You can either fetch the service and set data directly:

function (JavaScriptData $data)
{
    $data->set("my-key", $value);
}

The passed data needs to be JSON serializable.

Always try to pass the data locally at first (vor example via DataContainer s) instead of passing it globally.

This can improve discoverability.

A different way to add data is using data providers:

class MyDataProvider implements JavaScriptDataProvider
{
    /**
     * @inheritDoc
     */
    public function provideData (JavaScriptData $data, ?RequestContextInterface $requestContext, ?string $domain) : void
    {
        if (
            // we need the website later on
            !$requestContext instanceof WebsiteRequestContextInterface
            // only add data in the frontend
            || "app" !== $domain
        )
        {
            return;
        }

        $data->set("some-key", $this->fetch($requestContext->getWebsite()));
    }
}

Data providers are useful to add specific data in (nearly) every view (globally or within a specific domain).

Data providers will be called immediately before fetching, so possibly pretty late in the request.

To avoid weird “why is this value not included in my JS data” bugs, the data container is sealed after first reading it. If you try to fetch it a second time or try to write a value after fetching it, an exception will be thrown that directly shows you were the bug is.

Frontend

First you need to embed the data in your layout:

{{- mayd_javascript_data(context ?? null, "app", "_app-data") -}}
parameters
nametypedescription
contextRequestContextInterface|nullThe request context.
domainstring|nullThe domain to fetch the data for.
idstringThe id of the <script> tag.

Then you need to fetch the data in your JS:

// use the ID here, you passed above in the Twig function
const data = new DataContainer("_app-data");

Now you can access the data from your data container:

data.get<string>("test.key", "default-value");

Domains

To be able to separate backend data from frontend data, you can use domains.

You should stick to these domains:

  • mayd for data in the backend
  • app for data in the frontend
Table of Contents