beyondcode/nova-rss-card
beyondcode/nova-rss-card is a Laravel Nova card that displays RSS feeds directly on your dashboard. Add a feed URL to show recent posts in a clean, customizable card, giving teams quick at-a-glance updates without leaving Nova. Simple setup and customization make it a handy way to keep your team inf...
Before you install anything, read src/. This package is archived, last released 2018-08-23 at 0.0.1 ("experimental"), and targets the Nova 1.x card API. The correct first move is git clone the repo and read the card class, the Vue component, and composer.json constraints — not composer require. Treat it as a reference implementation of "fetch RSS → cache → render Nova card," not a dependency.
Prerequisites: Laravel Nova already installed (Nova is a paid product distributed via a private Composer repo, so feasibility testing requires a valid license and nova.laravel.com credentials). PHP with SimpleXML/ext-libxml.
Where to look first, in order:
composer.json — the laravel/nova and illuminate/* constraints. This tells you immediately whether a straight install is even possible on your Nova/Laravel majors. Expect conflicts.src/ card class — how the feed URL is passed in (constructor argument vs. a fluent setter; 2018 Beyond Code cards commonly used ->withMeta() or a setter), and where the fetch/parse happens.resources/js/components/Card.vue — how items are rendered, and whether it uses v-html on feed content.dist/js/card.js — the prebuilt asset Nova actually loads. If this is stale or built with an old Laravel Mix/Node 8 toolchain, you cannot rebuild it cleanly on modern Node; plan to port the .vue file into a first-party card instead.First use case: the standard Nova card registration. In app/Providers/NovaServiceProvider.php:
public function cards()
{
return [
(new RssCard)->url('https://example.com/changelog/feed.xml'),
];
}
Confirm the actual API against src/ — it may be new RssCard('https://…') or meta-based. A realistic first target is your own company changelog or release notes on an internal dashboard, visible to ops/support only.
Treat the fetch as yours, not the package's. The day-to-day pattern that actually works is to lift the fetch/cache logic into a small service and point the card at it:
$items = Cache::remember("rss:{$url}", now()->addMinutes(15), function () use ($url) {
try {
$response = Http::timeout(5)->get($url);
$xml = simplexml_load_string($response->body(), 'SimpleXMLElement', LIBXML_NONET);
return collect($xml->channel->item ?? [])->take(5)->map(fn ($i) => [
'title' => (string) $i->title,
'link' => (string) $i->link,
'date' => (string) $i->pubDate,
])->all();
} catch (\Throwable $e) {
report($e);
return [];
}
});
Return [] on failure. A card that 500s takes the whole dashboard down with it; an empty tile does not.
Multiple instances, multiple feeds. Register the card more than once with different URLs — one for the changelog, one for industry news — and constrain each with ->width('1/2') and, where supported, ->onlyOnDashboards() / ->canSee(fn ($request) => $request->user()->isOps()). This is the cheapest way to keep the tile off dashboards that don't want it.
Keep the URL developer-set. Never wire this to an admin-editable field without a validation/allowlist layer. A configurable server-side outbound fetch is an SSRF primitive the moment a non-developer controls the host.
If you rebuild (recommended): scaffold with php artisan nova:card acme/rss-feed, move the fetch into a FeedReader service (tested against a fixture XML file for both cache-miss and fetch-failure), and keep the Vue component to a v-for list of title + date + external link. That is roughly one engineer-day and gives you a card you own and can upgrade alongside Nova.
Sanitize before render. Strip tags from titles server-side, or render with {{ }} text interpolation in Vue. Do not v-html an untrusted feed description — a compromised feed becomes stored XSS inside an authenticated admin session.
composer require will likely fail or pin you. The 2018 constraints won't resolve against current Nova/Laravel/PHP. --ignore-platform-reqs is not a fix — it's a signal to fork or rebuild. If you fork, loosen the constraints in your copy and commit that.cards(), the service provider is registered, dist/js/card.js is present, and the component name in the card class matches the name registered in the JS. Browser console and the Nova API payload are more informative than PHP logs here.dist/. Editing the .vue and running npm run prod inside it will likely fail on a modern Node/Mix; a stale dist/ is what ships to the browser regardless of your source changes. This alone justifies porting the component into your app.simplexml_load_file($url) on a remote feed is unsafe by default on old PHP. Use LIBXML_NONET, avoid LIBXML_NOENT, and disable external entity loading. Older guides suggest libxml_disable_entity_loader(true) — that's deprecated in PHP 8; the parser defaults are safer now, but don't enable entity substitution.$xml->channel->item returns nothing for Atom (entry instead). Parse both or validate the source is RSS 2.0.app/Nova/Cards/, point the registration at your subclass, and keep the package only as a starting point — or skip the indirection and vendor the ~150 lines outright, which is cleaner than depending on an archived repo at 0.0.1.How can I help you explore Laravel packages today?