Skip to main content

Tag Helpers

Tombatron.Turbo provides tag helpers for rendering Turbo elements in Razor views.

Setup​

Add the tag helpers to your _ViewImports.cshtml:

@addTagHelper *, Tombatron.Turbo

turbo-frame​

Renders a <turbo-frame> element for partial page updates.

Attributes​

AttributeTypeDescription
idstringRequired. Unique identifier for the frame
srcstringURL to load content from lazily or on refresh
loadingstringLoading behavior: "eager" (default) or "lazy"
disabledboolWhen true, frame won't intercept navigation
targetstringNavigation target: "_top" breaks out of frame
autoscrollboolRestore scroll position after navigation

Examples​

Basic frame:

<turbo-frame id="cart-items">
<!-- Content here -->
</turbo-frame>

Lazy-loaded frame:

<turbo-frame id="comments" src="/posts/1/comments" loading="lazy">
<p>Loading comments...</p>
</turbo-frame>

Frame with refresh link:

<turbo-frame id="notifications" src="/notifications?handler=List">
@foreach (var notification in Model.Notifications)
{
<div>@notification.Message</div>
}
</turbo-frame>

<a href="/notifications?handler=List" data-turbo-frame="notifications">
Refresh Notifications
</a>

Disabled frame:

<turbo-frame id="preview" disabled="true">
<!-- Links and forms won't be intercepted -->
</turbo-frame>

Break out of frame:

<turbo-frame id="login-form" target="_top">
<!-- Form submission will navigate the whole page -->
</turbo-frame>

turbo​

Renders a <turbo-stream-source-signalr> element for real-time stream subscriptions.

Attributes​

AttributeTypeDescription
streamstringStream name(s) to subscribe to (comma-separated)
hub-urlstringSignalR hub URL (defaults to TurboOptions.HubPath)
idstringOptional element ID

Examples​

Subscribe to a specific stream:

<turbo stream="notifications"></turbo>

Subscribe to multiple streams:

<turbo stream="notifications,updates,alerts"></turbo>

Auto-generate stream based on user:

<!-- For authenticated users: user:{userId} -->
<!-- For anonymous users: session:{sessionId} -->
<turbo></turbo>

Custom hub URL:

<turbo stream="chat" hub-url="/my-signalr-hub"></turbo>

Generated Output​

For a single stream:

<turbo-stream-source-signalr stream="notifications" hub-url="/turbo-hub">
</turbo-stream-source-signalr>

For multiple streams:

<div data-turbo-streams="true">
<turbo-stream-source-signalr stream="notifications" hub-url="/turbo-hub"></turbo-stream-source-signalr>
<turbo-stream-source-signalr stream="updates" hub-url="/turbo-hub"></turbo-stream-source-signalr>
</div>

turbo-meta​

Renders one or more Turbo-related <meta> tags for configuring page-level Turbo behavior. This is a self-closing tag helper.

Attributes​

AttributeTypeDescription
refresh-methodTurboRefreshMethod?The refresh method: Morph or Replace
refresh-scrollTurboRefreshScroll?Scroll behavior during refresh: Preserve or Reset
cache-controlstringCache control directive (e.g., "no-cache", "no-preview")
visit-controlstringVisit control directive (e.g., "reload")

Enum Values​

TurboRefreshMethod

ValueDescription
MorphUses DOM morphing (idiomorph) to update the page, preserving state
ReplaceReplaces the entire page content (default Turbo behavior)

TurboRefreshScroll

ValueDescription
PreservePreserves scroll position during the refresh
ResetResets scroll position to the top after the refresh (default)

Examples​

Enable morph refresh with scroll preservation:

<turbo-meta refresh-method="Morph" refresh-scroll="Preserve" />

Generated output:

<meta name="turbo-refresh-method" content="morph">
<meta name="turbo-refresh-scroll" content="preserve">

Disable caching for a page:

<turbo-meta cache-control="no-cache" />

Generated output:

<meta name="turbo-cache-control" content="no-cache">

All attributes combined:

<turbo-meta refresh-method="Morph" refresh-scroll="Preserve" cache-control="no-cache" visit-control="reload" />

Generated output:

<meta name="turbo-refresh-method" content="morph">
<meta name="turbo-refresh-scroll" content="preserve">
<meta name="turbo-cache-control" content="no-cache">
<meta name="turbo-visit-control" content="reload">

Tip: Place <turbo-meta> in the <head> of your layout or page. Only attributes you set will produce <meta> tags — omitted attributes generate no output.

Best Practices​

Frame IDs​

  • Use descriptive, unique IDs: cart-items, user-profile, comment-list
  • For dynamic content, use prefixed IDs: item_123, comment_456
  • IDs must be unique across the entire page

Stream Names​

  • Use namespaced names: user:123, room:456, order:789
  • Keep names short but descriptive
  • Avoid special characters except :, -, and _

Performance​

  • Use loading="lazy" for below-the-fold content
  • Prefer specific frame updates over full page reloads
  • Minimize the number of active stream subscriptions

See Also​