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

Htmldev Bundle Laravel Package

zicht/htmldev-bundle

A Symfony bundle from Zicht that adds HTML development tooling to your app, providing helpers and debug utilities to streamline template work and speed up front-end iteration.

View on GitHub
Deep Wiki
Context7

Getting Started

The bundle is a Symfony integration for Zicht's "living styleguide" tooling: it renders Twig partials (patterns) with sample data in a dev-only route so you can develop markup and CSS in isolation from the application.

  1. Install as a dev dependency

    composer require --dev zicht/htmldev-bundle
    

    Treat it as dev tooling. If it is only in require-dev, CI jobs that render the styleguide need composer install without --no-dev.

  2. Register the bundle for dev/test only

    Symfony 4+ (config/bundles.php):

    return [
        // ...
        Zicht\HtmlDevBundle\ZichtHtmlDevBundle::class => ['dev' => true, 'test' => true],
    ];
    

    On older Symfony, add it to registerBundles() inside the if (in_array($this->getEnvironment(), ['dev', 'test'])) block of AppKernel.

  3. Import the routes in the dev routing config only

    config/routes/dev/htmldev.yaml:

    zicht_htmldev:
        resource: "@ZichtHtmlDevBundle/Resources/config/routing.xml"
        prefix: /styleguide
    

    Keeping this in config/routes/dev/ means the styleguide does not exist in production at all.

  4. Configure template paths and the base layout

    Inspect the available options rather than guessing:

    bin/console config:dump-reference zicht_html_dev
    

    Typically you point the bundle at one or more Twig paths containing your patterns and at a base template (the layout the styleguide page extends). Configure it as a Twig namespace as well if your patterns use @patterns/... includes.

  5. Create your first pattern

    Put a partial and its sample data next to each other, e.g. templates/patterns/button/button.html.twig plus whatever data file/definition the bundle expects for that pattern. Then add it to the styleguide index and visit http://localhost:8000/styleguide in the dev environment.

  6. First real use case

    Take an existing button/card/alert that is currently inlined in a page template, move the markup into templates/patterns/..., define the data variants you actually use (primary/secondary, with/without icon, long labels), and verify them in the styleguide. Then replace the inline markup in the application template with an {% include %}/{% embed %} so the styleguide and the app render the same file.

Where to look first: the bundle README and Resources/config/ (routing and service definitions), config:dump-reference, and the bundle's own templates under vendor/zicht/htmldev-bundle/Resources/views/ to see how patterns are discovered and rendered. Because the package has minimal adoption, read the source early — documentation is likely thin.

Implementation Patterns

Single source of truth in templates/patterns/

The most valuable workflow is not "a styleguide next to the app" but "the styleguide renders the app's own partials." Structure:

templates/
  patterns/
    button/button.html.twig
    card/card.html.twig
    card/card--compact.html.twig
  page/home.html.twig   {# includes @patterns/card/card.html.twig #}

Register templates/patterns as a Twig namespace so the app can include patterns without brittle relative paths:

twig:
    paths:
        '%kernel.project_dir%/templates/patterns': patterns

Then both the styleguide and the app use {% include '@patterns/card/card.html.twig' with { card: card } %}.

Variants as data, not duplicated markup

Define a base template and drive variants from sample data (state, size, modifiers). Keep variant definitions declarative so a designer can add a state without touching Twig control flow. If the bundle uses per-pattern data files, keep them next to the template and name them consistently — predictability matters more than the specific convention.

Use embed and macros for composable patterns

For patterns with slots, prefer {% embed %} over include with concatenated HTML strings:

{% embed '@patterns/card/card.html.twig' with { card: card } %}
    {% block card_footer %}
        {{ include('@patterns/button/button.html.twig', { label: 'Read more' }) }}
    {% endblock %}
{% endembed %}

Macros are the cleanest option for leaf components (buttons, icons, badges) because they take typed-looking arguments and have no output escaping surprises around whitespace.

Sample data should look like production data

If patterns accept entities or view models, define styleguide-only fixture objects (or use Doctrine fixtures/factories) instead of raw arrays. This catches the common failure where the styleguide renders {{ user.name }} against a plain array but the real entity exposes getName() differently. Keep the fixtures in a dedicated namespace, e.g. App\Styleguide\Fixtures, and never let production services depend on them.

Base layout hygiene

Point the bundle at a styleguide-specific base template that loads the same CSS/JS as the app (via encore_entry_link_tags/asset()) but skips analytics, CSRF, session-dependent chrome, and anything that requires a logged-in user. If you want the styleguide to sit inside the real chrome, use the app layout but stub out user-dependent blocks.

Navigation and grouping

Use subdirectories to create logical groups (forms, navigation, content). Order matters in a styleguide — name files with a numeric or alphabetical prefix if the bundle sorts by filename. A useful index makes the difference between a tool people use and one they forget.

Extending the styleguide page

If you need a custom index, global header, or extra panels, look for the bundle's controller/service definitions and either decorate the service or override the bundle's templates:

templates/bundles/ZichtHtmlDevBundle/

Override only the presentation; leave pattern discovery to the bundle.

CI smoke test

A living styleguide rots the moment a pattern breaks. Add a cheap functional test that requests the styleguide index (and, if discoverable, each pattern route) in the test environment:

public function testStyleguideRenders(): void
{
    $client = static::createClient();
    $client->request('GET', '/styleguide');
    $this->assertResponseIsSuccessful();
}

This turns "we broke a partial" into a red build rather than a bug found on staging.

Keep it out of the container in production

Because the bundle is registered only in dev/test, production container compilation and autoloading are unaffected. Don't be tempted to enable it in prod "just for a quick look" — the styleguide renders arbitrary sample data and may expose internal markup.

Gotchas and Tips

  • Unmaintained / low adoption. Stars and dependents are effectively zero, so expect no fixes and verify compatibility with your Symfony and PHP versions (composer why-not zicht/htmldev-bundle). Pin the version in composer.lock and be prepared to vendor/fork it. Check whether the bundle uses deprecated Symfony APIs before upgrading Symfony.
  • Dev-only bundle + dev-only routes must stay in sync. Registering the bundle in config/bundles.php but importing routes unconditionally (or vice versa) gives confusing "service not found" or 404 errors. Both belong in dev/test.
  • New patterns not appearing. Pattern discovery is often cached by the Symfony container or the bundle itself. After adding a pattern, run bin/console cache:clear (and check whether the bundle has its own cache warmer). In development, confirm you're editing the directory that is actually registered — a missing or mistyped Twig path is the most common cause of "empty styleguide."
  • Twig strict_variables. With strict variables enabled (common in dev), a pattern that renders fine in the app can explode in the styleguide because sample data is missing a key. This is a feature: it surfaces hidden assumptions. Fix the fixture, not the strictness.
  • Asset paths break in nested routes. Relative url() references in CSS and manually written <img src> paths can resolve differently from the app's routes. Always use asset() and your asset manifest, and make sure the dev build is compiled (yarn dev/npm run dev) before judging the styleguide.
  • Twig namespace vs filesystem confusion. The bundle's configured paths and Symfony's twig.paths are separate. An include that works via a filesystem path may fail via @patterns/... if the namespace isn't registered. Register namespaces explicitly and use them consistently everywhere.
  • Route prefix conflicts. A /styleguide prefix can collide with an app route or a firewall rule. If you use an access-control rule for ^/, verify the dev route isn't blocked or redirected to a login page.
  • Sample data drift. The styleguide is only "living" if the fixtures track reality. When a component's contract changes (new required field, renamed property), update the fixture in the same commit. Reviewing pattern diffs in code review is the cheapest enforcement.
  • Don't put secrets or PII in fixtures. Styleguide data is checked into the repository and rendered without authentication in dev; use invented names, emails, and tokens.
  • Escaping and whitespace. Inline-block and flex layouts are sensitive to whitespace emitted by Twig tags. Use {%- -%} deliberately and verify the pattern in the styleguide and in a real page; the surrounding layout can change rendering subtly.
  • Overriding bundle internals is supported, monkey-patching is not. Prefer template overrides under templates/bundles/ZichtHtmlDevBundle/ and service decoration over editing vendor/. If you need behavior the bundle doesn't expose, fork it into src/ or a small internal bundle — you'll need the fork option eventually given the lack of upstream maintenance.
  • Evaluate the exit cost up front. Since this is a single-purpose dev tool, the risk is contained: if the bundle breaks on a Symfony upgrade, you can replace the index/rendering layer with a small custom controller that renders the same templates/patterns/ directory. Keeping patterns in plain Twig with namespaced includes (rather than in bundle-specific constructs) makes that replacement trivial.
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.
uni-method/symfony-lib
tacticmedia/scim-server-bundle
neika-ai/symfony-bundle
mattleads/agent-publishing-bundle
glavweb/framework-bundle
glavweb/extra-bundle
glavweb/api-bundle
glavweb/admin-bundle
adachsoft/api-version-bundle
elsayed85/laravel-api-exceptions
ouhssini/laravel-demo-mode
daworks/ncloud-outbound-mailer-driver
gp247/cms
ignibyte/aic-gates
nexa-merchant/blog
novasa/laravel-language-center
opencage/geocode
adolfoholzer/parameters
livenetworks/ln-starter
shitoudev/permissionmanager