@portal
Transport content to different areas of the page
The @portal directive allows you to transport sections of your template code to another part of the page. This is essential for injecting scripts, styles, or content into specific locations like the page head or body, regardless of where your component appears in the document.
Syntax
@portal(destination)
<!-- Content to transport -->
@endportalWith additional parameters:
@portal(destination, id: "unique-id", includeOnce: true)
<!-- Content included only once -->
@endportalThe destination can be written bare (@portal(bodyEnd)) or quoted (@portal("bodyEnd")) — both forms are equivalent, and both appear in the core components.
Portal Destinations
pageStart
Before the opening <html> tag
pageEnd
After the closing </html> tag
headStart
At the start of the <head> element
headEnd
At the end of the <head> element
bodyStart
At the start of the <body> element
bodyEnd
At the end of the <body> element
Parameters
destination
Yes
The target location for the content (see destinations table)
id
No
A unique identifier for deduplication across multiple components
includeOnce
No
When true, ensures the content is only included once per page
Examples
Injecting Scripts at Body End
The most common use case is injecting JavaScript at the end of the body:
Include Once for Libraries
When including shared libraries like Alpine.js, use includeOnce to prevent duplicate includes when multiple instances of your component exist on the page:
Unique ID for Cross-Component Deduplication
When multiple different components might include the same library, use a consistent id to deduplicate across all of them:
Alpine.js Component Registration
Register Alpine.js components that your element depends on:
Mobile Menu at Body Start
Transport a mobile navigation overlay to the start of the body:
Preload Critical Resources
Add preload hints to the head for performance optimization:
Custom Styles in Head
Inject component-specific styles into the page head:
Modal Dialogs at Body End
Transport modal dialog markup to the end of the body for proper stacking:
Best Practices
Use
includeOncefor shared resources - Always useincludeOnce: truewhen including libraries or scripts that should only appear once on the page.Use consistent IDs across components - When multiple components might include the same resource, use the same
idto ensure proper deduplication.Prefer
bodyEndfor scripts - Loading scripts at the end of the body improves page load performance.Use reverse domain notation for IDs - Follow the pattern
com.yourcompany.featureto avoid ID collisions.Combine with conditionals - Use
@ifto conditionally include portal content based on component settings.
Related Documentation
Modals, Overlays & Portals - Overlay components built on @portal
Interactive Components with Alpine.js - Registering Alpine factories via portals
Integrating JavaScript Libraries - Loading libraries exactly once with includeOnce
Last updated
Was this helpful?

