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

peterbrinck/nova-laravel-news

A Laravel Nova card that brings Laravel News into your dashboard, showing recent articles and community updates without leaving the admin panel. Browse headlines at a glance and stay current with releases, tutorials, and packages.

View on GitHub
Deep Wiki
Context7

Getting Started

Step 0 — check your Nova version before anything else. Run composer show laravel/nova and note the major. This package's last release was March 2019, which puts it in Nova 1.x / early 2.x territory. On Nova 3+ the card base class, registration API, and asset publishing conventions changed enough that you should assume composer require fails or the card renders blank. That's not a dealbreaker — it's a fork signal, and the whole codebase is one card class plus one Blade view you can read in twenty minutes.

If you are on an era-appropriate Nova:

composer require peterbrinck/nova-laravel-news
php artisan vendor:publish --provider="Peterbrinck\NovaLaravelNews\CardServiceProvider"

Verify the actual namespace against the package's composer.json psr-4 block before you paste a provider class into a command — the vendor name in the README is not always the namespace. Then register the card in app/Providers/NovaServiceProvider.php:

public function cards()
{
    return [
        // ...
        new \Peterbrinck\NovaLaravelNews\LaravelNews(),
    ];
}

Where to look first, in this order:

  1. The card class — how it fetches, whether it caches, and what component() returns.
  2. The Blade view — whether it uses {{ }} or {!! !!} on feed content. This is your XSS answer.
  3. The published config — article count, feed URL, cache TTL.
  4. CardServiceProvider — auto-discovery, view namespace, any Nova::script() calls.

First use case: an engineering-only dashboard card. Don't put it on the main dashboard for everyone; gate it:

public function cards()
{
    return array_filter([
        new \Peterbrinck\NovaLaravelNews\LaravelNews(),
    ], fn () => request()->user()?->isDeveloper());
}

The first thing you should actually ship is the spike: get it rendering live data in a non-production environment, or confirm it doesn't, and decide build-vs-fork from that — not from the README.

Implementation Patterns

Fork-and-vendor the fetch, not the whole package

The durable part of this repo is the shape: card → cached feed → escaped list. Reproduce that shape against your installed Nova rather than fighting 2019 constraints. If you fork, lift the Composer constraints to your Laravel/PHP/Nova matrix and replace the fetch with the HTTP client so you get timeouts, retries, and testability for free:

class NewsRepository
{
    public function __construct(private string $feedUrl, private int $ttl = 30) {}

    public function latest(int $limit = 5): Collection
    {
        return Cache::remember("laravel-news.{$limit}", now()->addMinutes($this->ttl), function () use ($limit) {
            try {
                $response = Http::timeout(3)->retry(1, 200)->get($this->feedUrl);

                if (! $response->successful()) {
                    return collect();
                }

                return $this->parse($response->body())->take($limit);
            } catch (\Throwable $e) {
                report($e);

                return collect();
            }
        });
    }
}

report() rather than a silent catch matters — a blank card with no log line is the single most common support ticket for this pattern.

Warm the cache out of band

The card renders inside a synchronous /nova request. An uncached fetch means every dashboard load blocks on Laravel News. Either keep a sane TTL and a short timeout, or pre-warm:

// app/Console/Kernel.php
$schedule->call(fn () => app(NewsRepository::class)->latest())->everyThirtyMinutes();

That converts an availability risk into a non-issue and keeps dashboard latency flat when the feed is down.

Parse defensively

RSS is not a contract. Guard against shape changes:

protected function parse(string $xml): Collection
{
    $feed = @simplexml_load_string($xml);

    if ($feed === false || ! isset($feed->channel->item)) {
        return collect();
    }

    return collect($feed->channel->item)->map(fn ($item) => [
        'title'   => (string) $item->title,
        'link'    => (string) $item->link,
        'excerpt' => Str::limit(strip_tags((string) $item->description), 140),
        'date'    => (string) $item->pubDate,
    ]);
}

Escape at the view, not in the data layer

Feed titles and excerpts are third-party strings rendered inside an authenticated admin. {{ $article['title'] }} everywhere; {!! !!} nowhere. If the package's own view uses raw output, fix it in your published copy and treat that as the first commit on your fork.

Test it like a normal feature

Http::fake(['*' => Http::response($this->rssFixture(), 200)]);
Cache::flush();

$this->actingAs($dev)->get('/nova/dashboards/main')
    ->assertOk()
    ->assertSee('Laravel 12 Released');

And the failure path: Http::fake(['*' => Http::response('', 500)]) should render the fallback text, not a 500 page. Nova cards that throw inside render can take down the whole dashboard for that user.

Config surface

Expose article count and feed URL via config + env so you can tune without a deploy:

// config/nova-laravel-news.php
return [
    'url'      => env('LARAVEL_NEWS_FEED', 'https://laravel-news.com/feed'),
    'articles' => (int) env('LARAVEL_NEWS_COUNT', 5),
    'ttl'      => (int) env('LARAVEL_NEWS_TTL', 30),
    'enabled'  => env('LARAVEL_NEWS_ENABLED', app()->environment('production')),
];

Include the article count in the cache key (as above) or a config change silently returns the previous list for the full TTL.

Gotchas and Tips

The classic break is simplexml_load_file() on a remote URL. It depends on allow_url_fopen, which is disabled on a lot of hardened PHP builds and container images. Symptom: a warning-laden blank card while curl https://laravel-news.com/feed from the same host works fine. Fix: fetch with the HTTP client, parse with simplexml_load_string() on the body.

Nova major upgrades break the card API, not the feed. Card base class, component() naming, Nova::script()/Nova::style() vs the newer serving hooks — this is precisely the surface that changes between majors. Pin the package, record it in your internal tooling inventory with a named owner, and re-test the card as part of every Nova upgrade checklist. An abandoned card that 500s a dashboard during an upgrade crunch is a worse outcome than the feature is worth.

Blank card debugging runbook, in order:

  1. php artisan view:clear — a stale compiled view from a published override is a frequent culprit.
  2. Hit the feed in isolation: php artisan tinker → Http::get(config('nova-laravel-news.url'))->status().
  3. Check storage/logs/laravel.log — if nothing is there, someone swallowed the exception; that's a bug to fix, not a mystery.
  4. Confirm the card is actually registered for the dashboard being viewed (custom dashboards in Nova 2+ have their own cards() array).
  5. composer dump-autoload after any namespace change in a fork.

Cache negative results, briefly. If the feed is down, do not let every dashboard load retry it. Cache the empty collection for 60 seconds — long enough to protect the endpoint, short enough to recover quickly. Don't cache null with Cache::remember; it re-fetches on every call.

Watch the egress path. Locked-down VPCs, air-gapped builds, and some container network policies block outbound HTTPS from the web tier. The card will work in local, fail in staging, and confound you. Confirm egress before you write any code.

Local development: disable the card by default outside production (see enabled above). Otherwise every php artisan serve reload hits the feed, and you'll be the one tripping rate limits.

Extension points worth knowing: override the published Blade view to change markup; bind a stub NewsRepository in the container for tests; subclass the card to add filtering or read-state. Anything beyond a static headline list — curation, read tracking, notifications — is out of scope for this package and lives in your fork or your own card.

Scope it internally. This is defensible on an engineering-facing admin dashboard and nowhere else. Third-party Laravel News content on a client or agency dashboard is off-brand and not worth the conversation.

Ownership is the real cost, not the install. 17 stars, 0 dependents, no release since March 2019 — there will be no upstream fix, ever. MIT means fork-and-own is legally clean, but "we forked it and nobody owns it" is how this ends up as orphaned code someone discovers during a Nova 5 upgrade. Assign the owner in the same PR that adds the card.

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.
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
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox
pairus/product-data
fayne/laravel-filament-cms-core
nodisrupt/laravel-agent
sierratecnologia/media-manager