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 Card Laravel Package

idf/nova-html-card

idf/nova-html-card adds a Laravel Nova dashboard card that renders any HTML you give it, handy for notices, links, embeds, and lightweight widgets. Install via Composer, register the card, and pass your own markup to customize the Nova dashboard with custom content, no custom card class needed.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit. The package is essentially one class — Idf\NovaHtmlCard\HtmlCard — that subclasses Nova's card lifecycle and renders whatever string content() returns. There is no config, no routes, no migrations, no publishable assets, and no service provider surface to reason about. Architecturally this is not a framework dependency; it is a convention with a thin Nova glue layer. Everything you actually depend on (cards(), canSee(), $width, onlyOnDashboards()) belongs to Nova, not to this package. That distinction matters for risk: the package's own failure surface is nearly zero, and the real coupling is to a commercial, closed-source platform whose card API has churned across majors.

Integration feasibility. Three commands and one provider edit: composer require, generate a card class, extend HtmlCard instead of Nova's Card, register it in NovaServiceProvider::cards(). No schema changes, no data migration, no asset build. A single engineer can validate the whole thing in a staging branch inside a day, including a CSP and dark-mode pass. Reversibility is the strongest property in the evaluation — exit is deleting one subclass and one array entry.

Technical risk. Four items dominate, in order:

  1. Raw HTML injection into an authenticated admin DOM. That is the feature, and it is the primary security risk. Any user-, tenant-, or third-party-API-influenced value reaching content() becomes stored XSS on the highest-privilege session in the estate. Mitigation is a governance decision (engineers only, Blade files in version control, {{ }} everywhere) rather than a technical control the package provides.
  2. Nova version coupling. Nova is paid and closed-source; compatibility cannot be inferred from this package's release dates. composer.json constraints must be checked against the actual target Nova and PHP versions before any upgrade. Budget a fork-and-patch contingency — the card is forkable in an afternoon only if subclass diffs stay minimal.
  3. Provenance. 68 stars, zero dependents, single maintainer. There is no canary population; an upstream regression reaches your dashboard first. Pin 3.4.* and upgrade deliberately. Note that 3.4.2 is literally an asset rebuild plus CI changes — a patch bump is not a feature signal.
  4. Silent failure modes. CSP blocks inline scripts, styles, iframes, and third-party assets with no operator-facing error — you get a blank or half-styled box. A Blade exception inside content() likewise renders an empty wrapper. Both are worse than a visible error.

The composite score (6.48, opportunity 25.63) is consistent with this reading: a low-cost, low-ceiling convenience layer with contained but non-trivial platform coupling.

Key questions to resolve before adoption.

  • Which Nova major and PHP version are we pinned to, and does this package's constraint set actually cover them?
  • What authors admin-panel HTML in our org, and through what mechanism — a textarea, or version-controlled Blade?
  • What is our CSP posture on the Nova origin, and does it permit the embeds we intend (Grafana/Metabase/status pages)?
  • Do we have a named internal owner and an afternoon-scale fork capability, or does this become orphaned?
  • Does the request need reactivity, filters, polling, or charting? If yes, this is the wrong package — that is the triage signal, not a stretch goal.
  • Does procurement/security require an SLA or review trail this dependency cannot satisfy?

Integration Approach

Stack fit. Laravel + Nova only. Outside an existing Nova estate there is nothing to evaluate — Nova is a paid prerequisite, and this package delivers zero value without it. Inside Nova, the fit is exact: it occupies the same slot as a hand-written Vue card but collapses the build step. The decision is therefore not "adopt a library" but "adopt a default for static dashboard chrome."

Migration path. None required, and that is the point. There is no state to migrate, no schema, no persistence. Adoption is additive; rollback is a provider edit. The one deliberate design choice that protects the exit is keeping all markup in normal Blade views under resources/views/nova/cards/ rather than inline PHP strings — that makes a future migration or fork mechanical rather than archaeological. Do this from the first card, not after the fifth.

Compatibility work. Pin "idf/nova-html-card": "3.4.*". Validate against the exact Nova and PHP target in CI, not by reading release notes. Test in staging with production CSP headers, since a permissive staging CSP will hide the blank-card failure entirely. Check both Nova light and dark themes — hardcoded hex values and background: #fff are the most common cosmetic complaint about hand-authored card HTML.

Sequencing.

  1. Spike (staging). One link/onboarding card. Confirm Nova version constraint, PHP version, CSP headers, and both themes. Success criterion is a rendered card under production-equivalent headers, not a rendered card locally.
  2. Governance first, breadth second. Publish the content policy — engineers only, HTML in version-controlled Blade, {{ }} for every interpolation, raw markup reserved for strings we authored. This is a product decision, and it gates everything downstream.
  3. Ship one low-risk card to production. Changelog or "help & docs" strip. Proves the pattern, exercises the review checklist, costs hours.
  4. Codify the triage rule. Static, trusted, operator-controlled → this package. Interactive, filtered, live, charted → bespoke Vue card. Getting this into grooming removes the recurring "do we build a card for this?" debate.
  5. Introduce a per-style abstract base. One abstract NoticeCard with a $width and a notice() hook, thin concrete subclasses beneath. Prevents markup duplication across dashboards.
  6. Add caching and instrumentation before the count grows. content() runs on every dashboard request for every user who sees the card. Cache anything non-trivial with a short TTL; key file-derived content on filemtime().
  7. Attach a Nova-upgrade checklist item. Before any Nova major, re-verify constraints, plan the fork, and test the card set in staging.

Operational Impact

Maintenance. Code volume is negligible; the maintenance cost is concentrated entirely in the Nova upgrade tax and in content governance. Name an internal owner on day one — a single-maintainer upstream with zero dependents means no one else is watching. Pinning plus deliberate upgrades is the whole maintenance strategy, and it is sufficient at this scale. Set expectations that this is a convenience widget layer: no roadmap commitment should depend on it.

Support. There is no support relationship. 68 stars and one maintainer will fail most enterprise procurement bars, and there is no security review trail. Internal support means a runbook entry covering the two diagnostic steps that resolve most incidents: is content() returning a non-empty string, and is the card blank because of CSP or because of a silent Blade exception. Add both to the on-call notes.

Scaling. Cost scales linearly with card count, not with the package. Every card's content() executes per dashboard request per viewer, so a naive implementation quietly turns /nova into the slowest page in the admin panel with the query buried inside something nobody thinks to profile. Mitigations: cache with short TTLs, cap iframe embeds at roughly one per dashboard (each embed is both a page-load cost and an unmonitored external dependency), and treat dashboard p95 latency as the tracked metric — not card count. The $width property makes a three-card 1/3 header row (status, links, announcement) a cheap way to make a stock Nova dashboard look intentional.

Failure modes to plan for.

  • Stored XSS via tenant- or API-influenced content — the highest-severity mode; prevention is policy plus escaping discipline, not the package.
  • Blank card under CSP — silent, no operator-facing error; caught only by staging with production headers.
  • Dead iframe — an external BI or status dashboard goes down and the admin panel looks broken; each embed needs an owner and a removal path.
  • Performance regression — an uncached content() or an outbound HTTP call on every dashboard hit; content() must stay pure and cheap, no writes, no Artisan::call(), no network.
  • Nova upgrade breakage — the card registers but renders blank after a Nova major; validate in CI against the target version.
  • Silent upstream regression — nothing catches it before your users do, because no one else depends on the package.
  • Dark-mode breakage — cosmetic but chronic; use Nova's CSS variables and Tailwind utilities, and review both themes.

Ramp-up. Near-zero for a Laravel developer — one file, four extension points. The learning curve is entirely in the review discipline, not the API. Codify a short reviewer checklist: every interpolation escaped or explicitly justified, caching present for anything beyond a trivial lookup, both themes checked, CSP implications reviewed, $width chosen intentionally. Once that checklist exists, the package is genuinely an hours-level task per card and the build-vs-buy case for static dashboard content is settled in its favor. The moment a request needs a refresh button or live data, treat it as escalation to a bespoke Nova card rather than a reason to bend this one.

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.
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource