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

Nova Html Field Laravel Package

reedware/nova-html-field

Laravel Nova field that renders raw HTML directly within resource forms and detail screens. Embed custom markup, links, or inline content alongside standard Nova fields to build richer, more flexible admin panels without writing custom components. Simple to install and configure.

View on GitHub
Deep Wiki
Context7

Getting Started

Install and register

composer require reedware/nova-html-field

The package is a Nova field, so there is no separate service provider to register manually (Laravel package auto-discovery) and typically no nova:publish step. Confirm the composer.json constraint matches your Nova major version — the last tag is from October 2020, which places it in the Nova 3.x era.

First place to look

  1. README.md for the exact setter name used to pass HTML in (commonly ->html(...) or ->content(...) — verify against the source before relying on it).
  2. src/Html.php (or similarly named field class) to see the $component string and any fluent configuration methods.
  3. resources/js/components/Field.vue — check whether it renders with v-html (raw HTML output) or plain interpolation (escaped). This single detail determines whether the field does what you expect.

First use case

Drop it into a resource's fields() method wherever you currently abuse a Text field or a Heading to show static copy:

use Reedware\NovaHtmlField\Html;

public function fields(Request $request)
{
    return [
        Html::make('Instructions')
            ->html('<p>Upload a CSV with columns: <code>name</code>, <code>email</code>.</p>')
            ->onlyOnForms(),

        // ... real fields
    ];
}

The immediate wins are onboarding copy inside a form, legal/disclaimer blocks on detail screens, and computed summary panels that would otherwise need a custom Vue component.

Implementation Patterns

Static help text per form section

Html::make('Billing Notes')
    ->html(view('nova.partials.billing-notes')->render())
    ->onlyOnForms()
    ->hideFromIndex(),

Rendering a Blade partial keeps the markup out of PHP and lets you localize it (__()), reuse CSS classes from your Nova theme, and version the copy like any other view.

Dynamic HTML from model state

Because the field is resolved against the underlying resource, you can compute the HTML per record rather than hardcoding it:

Html::make('Status Banner')
    ->html(fn () => $this->resource->isOverdue()
        ? '<div class="text-red-500 font-bold">Overdue by '.$this->resource->days_late.' days</div>'
        : '<div class="text-green-600">On track</div>')
    ->onlyOnDetail(),

If the package does not accept a closure, fall back to ->resolveUsing(fn ($value) => ...) or compute in the resource's fields() method before returning the array — both patterns are common across Nova fields and behave identically here.

Section dividers and grouping

A make() with an empty or single-character HTML payload is a cheap way to break a 20-field resource into scannable blocks without writing a custom panel component:

Html::make('Shipping')->html('<hr class="my-4"><h3 class="text-lg font-bold">Shipping</h3>')->onlyOnForms(),

Conditional visibility

Use Nova's standard canSee / canSeeWhen to gate sensitive copy (internal notes, pricing disclaimers) so it never ships to unauthorized users — the HTML is rendered server-side into the payload, so canSee is a genuine security boundary, not just a UI hint.

Mix with onlyOn* scopes

The field is display-only, so be explicit about scope: ->onlyOnDetail() for long-form content, ->onlyOnForms() for instructions, ->hideFromIndex() almost always (index table cells are narrow and raw markup looks broken there).

Gotchas and Tips

Raw HTML means raw XSS risk. If any part of the string comes from user input, escape it yourself: e($model->user_note), not $model->user_note. Composing HTML with sprintf and unescaped values is the realistic way this field becomes a stored-XSS vector. Prefer Blade partials, which escape by default.

It is not a data field. Do not add ->rules('required'), ->sortable(), or ->searchable(). There is no attribute backing it, so validation and sorting will either error or silently no-op depending on Nova internals. Keep it out of any fillable reasoning.

Check the Vue component's rendering mode. If the component interpolates rather than using v-html, your tags will appear as literal text. If it uses v-html, Nova's content-security-policy configuration may strip inline <script> — which is usually what you want, but it will also surprise you if you were embedding a widget.

Nova 4/5 compatibility is unlikely. A 2020 release targets Nova 3.x's component registration and Field base class. If you are on Nova 4+, expect the field to render blank or throw on component resolution; test in a branch before adopting, and be prepared to fork and update the nova constraint plus the Vue component to Nova 4's laravel-nova import structure. With zero stars and zero dependents, there is no community pressure keeping it current — treat it as vendored code you may need to maintain.

Empty make() name can break layouts. Nova uses the name for labels and column headers; passing '' may render a stray header cell in detail view. Use a real name and hide the label CSS-side if needed.

Index/detail rendering differs. Even with hideFromIndex(), verify the detail page — some Nova fields apply different wrapper padding in detail vs. form contexts, so a <hr>-based divider may look correct in one and cramped in the other.

Clear view cache when iterating. If you render Blade partials into the field, a stale view:clear-worthy cache will make you think the field is broken. php artisan view:clear after editing partials.

Extension point. Subclassing the field class is the cleanest way to add your own sugar (->asPanel(), ->asWarning()) that wraps the HTML in your theme's classes — cheaper than a full custom Nova component and keeps the package's Vue side untouched.

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.
ippanelcom/laravel-sdk
adachsoft/changelog-linter
adachsoft/collection
payerurl/telegrambot-crypto-payment-instant-payout
dskripchenko/laravel-hybrid-search
riorizkyrainey/lara-ced
mehedimi/static-vel
zharp/zharp
nonsapiens/bigquery-model-sync
lgu-bayambang-ict-office/lgu-laravel-development-standards
andydefer/laravel-support
se7enxweb/flysystem
lampwick/laravel
jeslage/statamic-emojis
micahdshackelford/rmap-laravel
draftsmaninc/draftsman
square-bit/laravel-volition
himito/laravel-mailman
htinlynn/genius-helper
maco-studios/hephaestus