Tagixo Docs

Developer Documentation for Laravel, SDK integrations, and extensibility

Core Integration

Rendering and Preview Workflow

Understand the rendering pipeline for page, form, and carousel variants and how preview is generated.

Rendering and Preview Workflow

Input contract

The rendering layer expects:

  • structure
  • context
  • layout_variant
  • optional entity metadata for some preview flows

The structure is always:

{ "body": { ... }, "components": [ ... ] }

Main render entry point

The normal entry point is:

BuilderApiController::render() (handles POST /tagixo/builder/render), which dispatches to the appropriate renderer via BuilderApiService::render(structure, context, layoutVariant, entityType, entityId).

Render branches

  • Form context -> form preview renderer path
  • Page + carousel variant -> carousel preview branch
  • Default -> page renderer path

This branch selection is not cosmetic. The same data can produce different output depending on context and variant.

Default page path

The default path goes through PageRenderer::renderFromJson().

At a high level, it:

  1. normalizes structure
  2. rebuilds node hierarchy if needed
  3. renders modules through Blade views
  4. generates CSS through PropTypes and the style generator
  5. returns html, css, and optional fonts

This is the path you will use most often for page-like output.

Public page layout assembly

When you render a real public page, there is an additional layout-aware step:

PageRenderer::renderWithLayout(Page $page)

That step:

  1. resolves the page layout
  2. renders page body independently
  3. prepends header when available
  4. appends footer when available
  5. falls back per section to the global default layout when assigned layout sections are missing

Important:

  • body belongs to the page itself
  • header and footer belong to layouts
  • fallback is section-based, not whole-layout based

Native rendering helpers on built-in models

For consumers that use the package's Page, MailTemplate, and PdfTemplate Eloquent models, three helper methods on the models bake the full HTML+CSS+fonts result in one call — useful for cron jobs, mail dispatch, and PDF generation pipelines:

  • Page::renderFull(): string — returns the complete public HTML document (DOCTYPE + head + CSS + fonts + body) for the page. This is what PublicPageController calls when serving /{path?}.
  • MailTemplate::renderHtml(array $data = []): string — produces an email-ready HTML body (inline CSS where reasonable, restricted module set). Pass $data for variable substitution.
  • PdfTemplate::renderHtml(array $data = []): string — produces print-ready HTML. Pair with dompdf/dompdf (or any PDF engine) for the binary output.

These bypass the live builder pipeline and work directly off the persisted content JSON, so they are safe to call from queued jobs without booting any builder admin UI.

If your project uses custom Eloquent models instead of the package ones, replicate the pattern by injecting the appropriate renderer (PageRenderer, MailRenderer, PdfRenderer) and calling renderFromJson() against your stored structure.

Form preview path

When context=form, Tagixo uses a form-specific preview renderer.

That renderer:

  • interprets form modules and wrappers differently from page content modules
  • outputs embeddable form markup
  • combines component CSS with global variables

If you test a form payload through page assumptions, your output will look broken even if the saved data is valid.

Carousel preview path

When context=page and layout_variant=carousel, Tagixo switches to slider preview logic.

That logic:

  • renders a baseline structure first
  • extracts root sections as slides
  • resolves transition settings, autoplay delay, navigation, and pagination
  • wraps output in a dedicated carousel preview view

This is why slider support should be documented as a page variant, not as a separate context.

Preview URL flow

The preview flow is intentionally server-mediated and uses signed URLs (no cached payload):

  1. editor posts {context, entity_id} to POST /tagixo/builder/preview-url
  2. backend returns {preview_url, expires_in} — for page context the URL points at the entity's public slug; for mail/pdf it points at /tagixo/builder/preview-{mail|pdf}/{id}
  3. opening the URL hits the relevant renderer, which checks signature + _preview=1 + authenticated session before bypassing the published() gate

This gives you:

  • short-lived preview access (TTL via tagixo.preview.url_ttl_seconds)
  • user/session binding (auth required even with valid signature)
  • no token bookkeeping — the signature is the credential
  • consumer-side honour: your PublicPageController uses Page::isAuthorizedPreviewRequest($request) to honour the bypass for context=page

Why context discipline matters

Always keep context and layout_variant explicit when:

  • previewing
  • server-side rendering
  • exporting
  • caching render artifacts

Do not "guess" context at the edge of your system.

Debug checklist

  • Route receives expected context/layout_variant.
  • Module exists in bootstrap availableComponents.
  • Module view resolves correctly.
  • Prop shape matches expected schema.
  • Generated CSS contains expected groups.

Output contract

The render API returns:

  • html
  • css
  • fonts when relevant

Your host UI is responsible for injecting css and fonts correctly in preview contexts.

Production recommendations

In production, cache rendered artifacts per entity revision and invalidate only when content changes.

If your app renders high-traffic public pages, do not rebuild full output on every public request unless you have measured and accepted that cost.