Skip to content

Global properties

Overview

In most applications, some data needs to be available globally. This is generally the case, for instance, of the logged-in user, but it could be anything else. To answer to this need, you may use global properties.

Global properties are shared in every hybrid request — unless it's a partial reload — and can be accessed in the front-end using useProperty or useProperties.

From a middleware

The idiomatic way of defining global properties is to create a dedicated middleware and to share properties from there.

php
final readonly class ShareNavigation
{
    public function __construct(
        private Hybridly $hybridly,
        private NavigationBuilder $navigation,
    ) {}

    public function __invoke(Request $request, Closure $next): Response
    {
        $this->hybridly->persist(['navigation']);
        $this->hybridly->share('navigation', $this->navigation->getSidebarItems());

        return $next($request);
    }
}

It is generally a good idea to create a TypeScript declaration file to inform TypeScript about the properties that are shared globally. For instance, the declaration file for the example above could look like that:

ts
import 'hybridly'

declare module 'hybridly' {
	export interface GlobalHybridlyProperties {
		navigation: App.Navigation.SharedNavigationItem[]
	}
}

export {}

This makes useProperty type-safe and provides your editor with autocompletion.

From anywhere

In the eventual case where sharing data outside the middleware is needed, it is possible through the hybridly function.

php
hybridly()->share([
    'foo' => 'bar'
]);

While this is a useful escape hatch, it is not recommended. This way of sharing data being dynamic by nature, it is not possible to completely type it.

If possible, consider using the middleware instead.

Accessing global properties

The useProperty function provides typed dot-notation support for accessing global properties.

For instance, using the user property in the security array as shown in the earlier example would look like that:

ts
const user = useProperty('security.user')

useProperty returns a ref that will be updated if the data is changed.