Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Ux Metadata Laravel Package

krystal-sf/ux-metadata

krystal-sf/ux-metadata is a Laravel/PHP package for defining and managing UX metadata in your application, helping keep presentation details organized and consistent across views and components through a simple, configurable API.

View on GitHub
Deep Wiki
Context7

Getting Started

  1. Install the bundle

    composer require krystal-sf/ux-metadata
    

    If there is no Flex recipe, register it manually in config/bundles.php:

    return [
        // ...
        KrystalSf\UxMetadata\UxMetadataBundle::class => ['all' => true],
    ];
    
  2. Define your defaults in config/packages/ux_metadata.yaml — typically a site title suffix, default description, Open Graph image, Twitter handle, and locale. Check src/DependencyInjection/Configuration.php in the package for the exact key names before writing this file; config keys are the most likely thing to have shifted between tagged releases.

  3. Wire the renderer into your base layout. Symfony UX bundles usually expose either a Twig function or a Twig component that emits the <title>, meta description, canonical, Open Graph, and Twitter tags in one call. Expect something like:

    <head>
        {{ ux_metadata() }}
        ...
    </head>
    

    Confirm the exact name in src/Resources/views/ or in the README — this is the one line you cannot guess.

  4. First real use case: set a page-specific title and description from a controller action:

    public function show(Product $product, MetadataManager $metadata): Response
    {
        $metadata
            ->setTitle($product->getName())
            ->setDescription(strip_tags($product->getSummary()))
            ->setOgImage($product->getHeroImageUrl());
    
        return $this->render('product/show.html.twig', ['product' => $product]);
    }
    

Where to look first, in order: the README, src/ root for the manager/service and any value objects, Configuration.php for config keys, and src/Resources/views/ for the template you embed in <head>. Given the package shows zero dependents, treat the README as the source of truth and pin the version you integrate against.

Implementation Patterns

Default + override in the layout. Put the renderer in base.html.twig, define defaults in bundle config, and only override what a page cares about. This keeps controllers free of boilerplate and means a new page automatically gets a sane title pattern (Page Name | Site Name) rather than inheriting a stale global one.

Controller-driven metadata. Inject the metadata service into controllers (or a shared abstract controller) and set values before render(). For resource pages, derive title/description from the entity rather than hardcoding strings — this is where the bundle earns its keep compared to manually writing <meta> tags in each template.

Twig-driven metadata for template-owned pages. For marketing or CMS-style pages where the copy lives in the template, set values in a {% block %} near the top of the child template before the layout renders. Pick one convention — controller or template — per page type and stick to it, otherwise debugging "why is the title wrong" becomes a hunt across two layers.

Global rules via an event subscriber. For site-wide concerns (appending a brand suffix, setting og:site_name, defaulting an OG image per section) use a listener on kernel.controller or kernel.response rather than repeating logic. This is the cleanest extension point short of decorating the manager.

Turbo-friendly rendering. If you use Symfony UX Turbo, <head> metadata is not re-evaluated on Turbo navigations unless you handle it. Listen for turbo:load (or re-render the metadata block server-side per visit) so titles and OG tags stay correct after in-app navigation. Without this, the first page load looks right and everything after it silently inherits the original metadata.

Structured data / JSON-LD. Where the bundle supports it, feed the same value object you use for meta tags into a JSON-LD block for products, articles, and breadcrumbs. Keeping one source of truth avoids the classic mismatch between the visible description and the structured-data description.

Composition over duplication. Create a small internal helper (e.g. App\Metadata\PageMetadataFactory) that turns your domain objects into metadata calls. When the package's API changes — likely, given the maturity level — you update one class instead of every controller.

Gotchas and Tips

  • Config cache. After editing ux_metadata.yaml, run bin/console cache:clear. Silently ignored config keys are usually a typo in the key name against Configuration.php, not a bug.
  • Tag order and escaping. Metadata values flow into HTML attributes. Set plain text, not HTML; strip tags from entity-derived descriptions and let Twig escape the rest. Double-escaping (&amp;amp;) is the usual symptom of pre-escaping before passing values in.
  • HTTP caching. If any metadata is per-user (e.g. "Cart (3 items)" in the title), you will poison shared caches. Either keep metadata anonymous-only or vary the cache key appropriately. This bites in production far more often than in dev.
  • Turbo snapshot cache. Beyond turbo:load, be aware Turbo caches page previews; metadata can briefly show the previous page. If that matters, disable preview caching for affected links or ensure the metadata block is inside the cached body.
  • Package maturity. With zero dependents, expect API churn. Pin the exact version in composer.json, and wrap calls behind your own service so a breaking change is a one-file fix. Read the CHANGELOG between upgrades.
  • Debugging. dump() the metadata object just before render, and check the rendered <head> in a WebTestCase assertion (assertSelectorTextContains('title', ...), assertSelectorExists('meta[property="og:title"]')). Assertions catch regressions when defaults or suffix logic change.
  • Extension points. Prefer (1) decorating the manager service, (2) a kernel event subscriber, (3) a custom Twig template override, in that order. Overriding the bundle's template wholesale makes future upgrades harder than decorating.
  • Fallbacks for missing values. Decide explicitly what happens when description or og:image is unset — inherit the default, omit the tag, or throw in dev. Silent omission is usually right; it prevents empty content="" attributes that some crawlers flag.
  • Don't reimplement <title>. If you keep a manual <title> in the layout alongside the bundle's output, you get duplicate tags. Remove the hand-rolled tags when you adopt the bundle, and grep templates for og: and twitter: to catch stragglers.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
coleus/frame
thtg88/journalism
filagora/filagora-ai-forums
rlacerda83/query-parser
socialdept/atp-orm
cboxdk/laravel-assistant-client
socialdept/atp-resolver
socialdept/tenant-domains
tautvydasr/blade-class-names
socialdept/color-scales
maherelgamil/controller
coleus/widgets
coleus/table
coleus/users
coleus/music
coleus/health
coleus/calendar
coleus/notes
coleus/support
coleus/settings