Skip to content

Frontend Page And Site Loading

Capell frontend requests resolve site, language, page, layout, and theme state before the public renderer runs.

Use this when changing capell-app/frontend routing, cache behavior, runtime selection, or request-scoped frontend state.

  • A request enters the app and the Frontend middleware invokes the Frontend Kernel.
  • The Kernel builds a FrontendWork with the HTTP request and a FrontendState (scoped per request).
  • The Kernel runs a sequence of steps (a Laravel Pipeline) to resolve site/domain/language, page, layout, theme, and build a renderable context.
  • The result is a FrontendBootstrapResult that may contain:
    • redirect: an early redirect, such as a default-site redirect.
    • error: HTTP error details, such as a 404 for bots.
    • context: the resolved FrontendContext used by rendering.

FrontendServiceProvider registers the key interfaces used by the pipeline:

  • UrlSignatureVerifierInterface maps to FrontendUrlSignatureService.
  • AssetsRegistryInterface maps to FrontendAssetsService.
  • FrontendSettingsReaderInterface maps to FrontendSettingsReader.
  • SettingsMigrationProviderInterface maps to FrontendSettingsMigrationProvider.
  • FontMimeTypeResolverInterface maps to FontMimeTypeResolver.
  • FrontendResponseRendererRegistry is scoped and registers Blade and Livewire response renderers.
  • RenderedModelTracker is scoped and defaults to NullRenderedModelTracker.

Scoped state:

  • FrontendState is scoped per request.
  • FrontendContextReader resolves to FrontendState.
  • The Frontend facade resolves FrontendContextReader; it is a Laravel facade over the scoped reader, not a separate frontend-context wrapper.
  • FrontendKernelInterface is scoped and receives the scoped FrontendState.

Kernel registration:

  • FrontendKernelInterface is bound to FrontendKernel with the steps from config('frontend.kernel.steps').
  • The default steps are:
    1. SiteResolveStep
    2. SetUrlGeneratorStep
    3. PageResolveStep
    4. LayoutResolverStep
    5. ThemeResolverStep
    6. RegisterThemeViewsStep
    7. NotifySubscribersStep

Aux services:

  • ThemeViewRegistrar is a singleton. It implements Core’s Octane reset contract so a theme registered for one request cannot remain in the capell:: view namespace for the next long-running worker request.
  • FrontendCachePolicy is a singleton.
  • LayoutWidgetRegistry from capell/core provides frontend Blade and Livewire component aliases.
  • OnFrontendContextResolved is a singleton listener.
  • The URL generator binding switches to SiteUrlGenerator when capell-frontend.use_site_domain_for_urls is true. Otherwise it uses Laravel’s UrlGenerator.

ResolveFrontendRuntimeAction owns the generic Blade, Livewire, and Inertia runtime decision. Optional packages that need extra public frontend runtime flags should not be referenced directly from capell/frontend; they should implement Capell\Frontend\Contracts\FrontendRuntimeManifestContributor and tag the implementation with FrontendRuntimeManifestContributor::TAG.

Contributors receive the resolved FrontendContextReader and mutable FrontendRuntimeManifestData, letting add-ons contribute runtime flags while frontend remains safe to install on its own.

  • SiteResolveStep: resolves the site, language, domain, and canonical page-relative path from the full URL. It assigns that path to both FrontendState::effectiveUrl() and FrontendState::relativePath() and may redirect to the default site when enabled.
  • SetUrlGeneratorStep: applies the frontend URL generator state for the resolved request, then restores Laravel’s previous forced root and scheme when the step finishes or throws.
  • PageResolveStep: resolves the target page, supports wildcard routes, error page fallback, and returns 404 for bot user agents when no page is found.
  • LayoutResolverStep: chooses the layout for the resolved page.
  • ThemeResolverStep: chooses the theme for rendering.
  • RegisterThemeViewsStep: registers theme view paths for Blade.
  • NotifySubscribersStep: emits FrontendContextResolved with an immutable snapshot of the scoped state.
  • Redirects short-circuit the pipeline and return immediately from the Kernel.
  • Errors also short-circuit; bots receive an immediate 404 when the page cannot be resolved.
  • capell-frontend.redirect_default_site: When true, unresolved domains redirect to the default enabled SiteDomain.
  • capell-frontend.use_site_domain_for_urls: Switches URL generation to include site domain rules.
  • capell-frontend.debug_log: Adds extra debug logging in resolution steps.
  • frontend.kernel.steps: Overrides the pipeline step list when an application needs a custom frontend bootstrap sequence.

ParseUrlStep and NormalizeDomainPathStep remain available as deprecated no-op compatibility steps throughout 1.x. Custom pipelines should remove them; both classes will be removed in 2.0.

  • FrontendCachePolicy, PageModelCache, PublicPageRenderDataCache, PageListingCache, and PageHydrator manage frontend cache behavior.
  • Read the Frontend guide for HTML caching details.

Frontend keeps request-specific rendering state out of public singletons wherever possible. When a singleton is unavoidable, it must implement Capell\Core\Octane\Resettable and be tagged with Resettable::TAG so Core can flush it after an Octane operation.

The built-in resettable frontend service is:

  • ThemeViewRegistrar, which restores the default capell:: Blade namespace.

Cache invalidation dependency declarations live in a boot-lifetime singleton so package registrations survive between Octane operations. The execution registry and its request-aware collaborators are scoped and replaced automatically for each operation; neither lifetime is reset-tagged. Fragment cache directive compilation is also scoped and is not reset-tagged.

Do not store the current site, page, language, theme, preview context, signed URL, or admin/editor state in an untagged singleton. Use scoped bindings for request state and use resettable singletons only for services that genuinely need to survive container boot.

Unit and integration tests validate the pipeline contracts:

  • Integration: FrontendKernelTest boots the kernel end-to-end.
  • Unit and integration coverage includes kernel steps, rendering strategy behavior, site/page loader behavior, cache helpers, and public rendering contracts.