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

Website Templates Bundle Laravel Package

w3c/website-templates-bundle

Symfony bundle maintained by the W3C that packages reusable Twig templates, layouts, and front-end components from the W3C website. It helps teams assemble accessible, standards-compliant pages faster, with consistent structure and styling for Symfony applications.

View on GitHub
Deep Wiki
Context7

Getting Started

The first thing to internalise: w3c/website-templates-bundle is a Symfony bundle, not a Laravel package. composer require w3c/website-templates-bundle will install, but Laravel's package discovery has nothing to register — there is no Illuminate\Support\ServiceProvider, no config/ merge, no publish tags. Treat it as a template and asset source, not a runtime dependency you composer require and forget.

Where to look first (inside vendor/w3c/website-templates-bundle/):

  • templates/ — the Twig layout, header, footer, navigation, breadcrumbs and language switcher. This is the actual value of the package.
  • assets/ (or Resources/) — the compiled/source CSS, JS, fonts and W3C logos that the markup expects.
  • translations/ — XLIFF/YAML catalogs for the UI strings (skip links, nav labels, footer text).
  • DependencyInjection/Configuration.php — the config tree; this tells you exactly what the bundle considers configurable (nav items, footer links, logo URLs) versus hardcoded.
  • LICENSE — read this before anything else, see Gotchas.

Pick your integration mode before writing code. There are three realistic ones:

  1. Port to Blade (most common for a Laravel shop). Copy the Twig templates, convert to Blade, move assets into resources/ + Vite. You lose upstream updates but gain full control.
  2. Symfony sidecar. If the deliverable is genuinely a W3C-branded microsite and you control the stack, build it in Symfony and use the bundle natively. Don't fight it inside Laravel.
  3. Reference only. Use the markup as the accessibility/design spec and hand-write your own Blade components that match the output byte-for-byte where it matters.

First use case to target: a public-facing site that needs the W3C masthead — logo, global nav, search, language switcher, skip-to-content link, footer — with correct ARIA landmarks. That's the 90% case and the part you should port first.

Minimal port in Laravel:

composer require w3c/website-templates-bundle
cp -r vendor/w3c/website-templates-bundle/templates resources/views/w3c
cp -r vendor/w3c/website-templates-bundle/assets resources/w3c-assets

Then convert layouts/base.html.twig into resources/views/layouts/w3c.blade.php and wire the CSS into vite.config.js. Get one page rendering with the real header and footer before touching anything else.

Implementation Patterns

1. Layout inheritance → Blade layout + stacks. The bundle's base template exposes Twig blocks ({% block content %}, {% block head %}, etc.). Map these to a Blade layout with @yield/@section and @stack('head') / @stack('scripts'). Keep the block names close to the originals so a future re-sync is a diff, not a rewrite.

2. Partials → Blade components. Every Twig {% include '@W3CWebsiteTemplates/header.html.twig' %} becomes a component:

{{-- resources/views/components/w3c/header.blade.php --}}
<header id="w3c-header" class="w3c-header">
    @include('components.w3c.skip-link')
    @include('components.w3c.logo')
    @include('components.w3c.nav', ['items' => $navItems])
</header>

Call as <x-w3c.header />. Do not wrap it in your own <header> — the component already emits the landmark.

3. Drive nav/footer from config, not hardcoded markup. Mirror the Symfony config tree in config/w3c.php:

return [
    'logo_url' => '/img/w3c-logo.svg',
    'navigation' => [
        ['label' => 'Standards', 'url' => '/standards'],
        ['label' => 'Groups',   'url' => '/groups'],
    ],
    'footer_links' => [ /* ... */ ],
    'locales' => ['en', 'fr', 'ja'],
];

This keeps the ported templates close to the original structure and makes per-environment overrides trivial. Share it via a view composer so components don't need it passed manually.

4. Assets through Vite, not asset(). Symfony's asset() and path() helpers don't exist in Blade. Rewrite every {{ asset('bundles/w3cwebsitetemplates/css/...') }} to @vite(...) or {{ Vite::asset(...) }}. Import the bundle CSS in resources/css/app.css and let Vite fingerprint it. If you must keep raw files, publish them to public/vendor/w3c/ with a small custom Artisan command and reference them with asset('vendor/w3c/...').

5. Translations as a one-time conversion. Don't try to load XLIFF at runtime. Convert the catalogs into lang/{locale}/w3c.php with a throwaway script, then use __('w3c.skip_to_content') in Blade. Keep the key names identical to the bundle's keys so you can diff when upstream adds strings.

6. Sync strategy — pin and mirror. Because the package has zero dependents and modest star count, you should assume no one else will catch a breaking change for you. Recommended workflow:

  • Pin w3c/website-templates-bundle to an exact version in composer.json.
  • Keep your ported Blade under a w3c/ subfolder with a header comment recording the upstream version and commit.
  • On upgrade, diff vendor/.../templates against your recorded copy and apply changes deliberately.
  • Commit the original Twig side-by-side in docs/upstream/ if your team reviews changes — it's cheap and makes the diff meaningful.

7. If you stay on Symfony. Register W3C\WebsiteTemplatesBundle\W3CWebsiteTemplatesBundle in config/bundles.php, add a w3c_website_templates: block to config/packages/, and reference templates as @W3CWebsiteTemplates/base.html.twig. Override by adding a templates/bundles/W3CWebsiteTemplates/ directory — Symfony's bundle override path wins without forking.

8. Test the markup, not the visuals. The bundle's output is an accessibility contract. Add HTML snapshot tests for header/footer and run axe-core (e.g. @axe-core/playwright) in CI. Assert the presence of: one <header> landmark, one <footer>, a working skip link as the first focusable element, aria-current="page" on the active nav item, and lang on <html>. These are the things a Blade port silently breaks.

9. Theme with custom properties. The bundle's CSS is structured around classes the bundled JS depends on. Override colours/typography via CSS custom properties in your own stylesheet loaded after the bundle CSS, rather than editing the bundle or adding !important rules.

Gotchas and Tips

Licence is NOASSERTION. Composer will report an unknown licence. That is a genuine blocker for any commercial release until someone reads LICENSE in the repo (W3C typically uses the W3C Software and Document Notice, but confirm). Get written sign-off, preserve the notice in your ported files, and don't strip copyright headers from the CSS/JS.

Blade and Twig collision. If you use twigbridge to render the bundle's templates directly rather than porting, configure Twig's delimiters away from {{ }} or Blade will try to compile Twig's {{ trans(...) }} as a PHP echo. Mixing the two engines in one view tree is almost always a worse outcome than a clean port — pick one and commit.

Missing helpers fail loudly at render, silently in review. path(), asset(), trans, is_granted() and Symfony's form_* functions appear inside the templates. Every one you miss becomes a Call to undefined function only when that branch renders — i.e. in the language switcher on a non-English page that nobody tested. Grep the Twig source for {{ and {% and tick each one off.

Class and ID names are load-bearing. The bundle's JS selects on specific IDs (menu toggles, search expanders). Renaming #w3c-menu to #site-menu for "consistency" kills the mobile nav with no error. If you must rename, rename in the JS too and add an integration test that opens the menu.

Hardcoded bundle asset paths. Expect bundles/w3cwebsitetemplates/... strings scattered through the templates. They 404 silently (an unstyled page, not a 500) once you move to Vite. Check the network tab on first render, not just the page.

Nested landmark duplication. The most common porting mistake: wrapping the bundle's <header> in your app's own <header>, or including the footer component inside a <footer> in your layout. Two banner/contentinfo landmarks is an axe violation and a screen-reader annoyance. Let the components own their landmarks.

Translation keys fall back to the key string. A missing w3c.skip_to_content renders literally as w3c.skip_to_content in the skip link. Add a CI check that no rendered page contains w3c. in visible text.

Version skew between templates and assets. The CSS and Twig are released together and assume each other. Copying templates/ from one version and leaving assets/ on another produces subtly broken layout that's painful to debug. Always move both in the same commit.

Debugging checklist when something looks wrong: (a) view source — did the component render at all? (b) network tab — 404s on CSS/JS? (c) @vite manifest stale after a copy — npm run build again; (d) compare your rendered header byte-for-byte against the upstream template output for the same config.

Extension points, in order of preference: (1) config for nav/footer links, (2) CSS custom properties for theming, (3) Blade component overrides for structural changes, (4) forking the templates — only when upstream is dormant, which given the dependents count is a real possibility. Keep your overrides in one directory so the next developer can see exactly how far you've drifted.

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.
3mdikram/worldmoneywords
snowsoft/config
itmosoft/laravel-subscriptions
larva/laravel-ai-qwen
diephp/sequences
users-au/socialite-provider
twidpay/twid-logger
mrnewport/laravel-plaid
mrnewport/laravel-repo
mrnewport/laravel-docsign
mrnewport/laravel-stow
mrnewport/laravel-flow
mrnewport/laravel-priceable
mrnewport/laravel-nestedterms
fredmeng/laravel-apidoc-generator
itstructure/laravel-multilingual-tools
pdustdar/elasticsearch
markupai/php-sdk
rlacerda83/lumem-microservice-shipment
uni-method/symfony-lib