storyfeed / ui
Renderers for Storyfeed activity feeds: a Blade component kit, with Vue/Inertia, Livewire and React following.
Requires
- php: ^8.4
- storyfeed/storyfeed: ^0.10.0 || dev-main
Requires (Dev)
- laravel/pint: ^1.18
- orchestra/testbench: ^10.0
- pestphp/pest: ^4.0 || ^5.0
- phpstan/phpstan: ^2.0
Suggests
None
Provides
None
Conflicts
None
Replaces
None
This package is auto-updated.
Last update: 2026-09-26 19:35:36 UTC
README
Storyfeed UI is a free, MIT-licensed set of renderers for Storyfeed activity feeds: components that take a page of the feed and draw it. Blade first, then Vue/Inertia, with Livewire and React following.
It works the way Laravel's pagination does. Core hands you the data, a
FeedPage whose items read as Storyfeed\Support\FeedItem, and this package
renders it with default Blade views you can publish and restyle.
The detail forms moved to core on 2026-09-14.
Markdown,Fields,Excerpt,FileandMediaObjectareStoryfeed\Detail\*instoryfeed/storyfeed, and their storage names gained a segment:Storyfeed/Detail/Excerpt. Their names always saidStoryfeed/rather thanstoryfeed-ui/, because a detail's name must not contain the library that defined it — so the vocabulary was core's while the classes were not. This package is the renderers.
Early development. This package currently depends on Storyfeed's
dev-mainbranch. Its API can change without a deprecation cycle. Commit your application's Composer lockfile to keep installations reproducible.
Installation
Requires PHP 8.4 or later in the PHP 8 series. The current test harness uses Laravel 12; CI runs PHP 8.4 and 8.5 on Ubuntu and Windows with lowest and stable dependencies.
composer require storyfeed/ui
The service provider registers itself through package discovery.
Storyfeed UI uses Tailwind CSS v4 and its Typography plugin. Install the plugin:
npm install -D @tailwindcss/typography
Register the plugin and the package's views in your application's
resources/css/app.css file:
@source "../../vendor/storyfeed/ui/resources/views"; @plugin "@tailwindcss/typography";
Compile your application's CSS with npm run build. Your layout must load
the compiled CSS, for example with @vite('resources/css/app.css').
Usage
Pass a page of the feed to a view:
use Illuminate\Http\Request; use Storyfeed\Facades\Storyfeed; Route::get('/', fn (Request $request) => view('feed', [ 'page' => Storyfeed::feed()->cursor($request->query('cursor'))->get(), ]));
Render the page with the feed component:
<x-storyfeed::feed :page="$page" />
Attributes on the tag, such as class, land on the feed's root element. The
empty slot replaces the words shown for an empty page:
<x-storyfeed::feed :page="$page"> <x-slot:empty>Nothing has happened yet.</x-slot:empty> </x-storyfeed::feed>
Components
<x-storyfeed::feed> is built from smaller anonymous components, and each one
can be used on its own:
| Component | Draws |
|---|---|
<x-storyfeed::feed :page> |
the page, then a link to older activity |
<x-storyfeed::item :item> |
one item: an activity, a group or a summary row |
<x-storyfeed::activity :activity> |
an activity row |
<x-storyfeed::group :group> |
a group row, its members behind a disclosure |
<x-storyfeed::digest :digest> |
a summary row: a person's day, or a crowd |
<x-storyfeed::headline :headline> |
a headline, each entity linked |
<x-storyfeed::glyph :glyph :intent> |
the icon disc |
<x-storyfeed::time :at> |
when it happened |
<x-storyfeed::thread :thread> |
what an activity quotes |
<x-storyfeed::media :image> |
a picture |
<x-storyfeed::body :body> |
one body, by its type |
<x-storyfeed::pager :cursor> |
the link to the next page |
Each of core's body types has a component in components/body: key-value,
excerpt, prose, file, item-list and media-object. A body
type with no component draws nothing.
Prose displays plain text and unknown media types as escaped text. It parses Markdown with raw HTML and unsafe links disabled, and sanitizes rich HTML at render time using Symfony's HTML Sanitizer. Verbatim content is always escaped and preserves its source whitespace.
Styling
The components use Tailwind's zinc palette for text, borders, and surfaces,
and indigo for links. To change these styles, publish the views and edit their
utility classes. You may also customize Tailwind's existing theme variables,
such as --color-indigo-700 and --color-indigo-300, in your application's
@theme block. These changes apply to every component using those colours.
The kit defines no additional theme variables. ItemList, Prose, and Excerpt use the
Typography plugin's prose styles.
The components include dark: variants and follow your application's
Tailwind dark mode configuration.
Icon intents are application-defined strings exposed through data-sf-intent.
To assign colours to your intent values, add the corresponding Tailwind
utilities to the published components/glyph.blade.php view.
Customising the Views
Publish the views to change the markup:
php artisan vendor:publish --tag=storyfeed-views
They land in resources/views/vendor/storyfeed, and a view there replaces
the package's. You only need to keep the files you change.
Icons. The payload's glyph is a token, such as shopping-bag, and the kit
ships no icon set. Draw a token by adding
resources/views/vendor/storyfeed/icons/shopping-bag.blade.php. A token with
no view draws icons/activity.
Your own body types. A body type draws the component named after it:
Acme/Attachment draws
resources/views/vendor/storyfeed/components/body/acme/attachment.blade.php,
which receives the body as $body and its entity as $entity.
Words. Headline words such as "Someone" and "a removed order" are core's
translation lines (php artisan vendor:publish --tag=storyfeed-translations).
The kit's own words, such as "Older activity" and "Show all :count", are plain
__() strings: translate them in your lang/{locale}.json.
Licence
MIT. See LICENSE.md.
The paperclip icon is from Heroicons, copyright Tailwind Labs, Inc., used under the MIT licence. The full notice is included in licenses/heroicons.txt. The attachment row layout is original work.