Real work rarely happens on one page.

You're halfway through a form and need to check something in another screen. A dashboard is streaming numbers you can't afford to lose track of. A video is mid-playback. Normally, you leave and hope the page is still the way you left it.

Earmark fixes that. It's a package for Laravel Livewire apps that parks a page in a panel while it keeps running. Watch it work:

Want to click around yourself? The live demo is open.

Park a page, keep your place

Press + and the page steps into the panel. Click it later and it swaps back onto the stage. No page load.

While it's parked, charts keep streaming, Livewire components keep polling, videos keep playing, and a half-filled form keeps every character you typed. By default, up to four saved views stay fully live.

You can pop a saved view out into a window that stays on top. The panel can sit on the left, the right, or along the bottom. Motion runs on spring physics, so it feels like something physical moving, not a menu opening.

Earmark's Switcher layout showing a grid of live previews of a dashboard, inbox, calendar, and form over the page

Earmark's Theater layout with the calendar page tightened to one side and saved views tiled beside it

Every visitor can change the layout, the edge, and the motion from the settings gear, and their choice is remembered.

The Earmark settings panel with Layout, Position, and Motion tabs next to the live panel

Why not just use browser tabs?

A tab remembers where you were. It doesn't show you what changed while you were gone.

Tabs are great for pages you read. You open one, read it, close it, and the browser treats every background tab as something that can wait.

That's literal. Chrome throttles timers in hidden pages, down to once a minute after five minutes hidden. Livewire cuts polling requests by 95% in a backgrounded tab. A tab also shows you a title and a favicon, not the view itself.

Now picture who works in one app all day. A cashier at a register. A support agent with a live queue. An operator watching a heads-up display. A power user in a SaaS dashboard. Each has one or two main views and a handful more to jump between, and the page in the background is often the one they're watching.

That's who Earmark is for. Your app decides what the workspace looks like, and with the database store a person's saved views follow them across devices. A browser tab can't do either. If you're building a SaaS product or an internal tool, that's the difference.

How it keeps pages alive

Moving a page's elements the ordinary way removes and reinserts them, which resets iframe state. I checked the Livewire 4.4 source, and @persist does exactly that during a wire:navigate swap. A YouTube embed would reload on every click.

So Earmark moves its layers with Element.moveBefore(), which shipped in Chrome 133. Nothing detaches, so nothing reloads.

Drop it into your app

Any Livewire layout. Install the package and wrap your layout's content in one component:

composer require pixelworxio/earmark
<body>
    <x-earmark>
        {{ $slot }}
    </x-earmark>
</body>

That's it. Earmark ships its own compiled script and styles and emits them itself, so there's nothing to add to Vite or Tailwind. Options go on the component, like side="right", preset="glide", or :live-limit="6". To set defaults for the whole app, publish the config with php artisan vendor:publish --tag="earmark-config".

Filament. No plugin needed. Register one render hook in a service provider and Earmark takes over the main content area, while the sidebar and topbar stay shared. Your panel must use ->spa().

use Filament\Support\Facades\FilamentView;
use Filament\View\PanelsRenderHook;
use Illuminate\Support\Facades\Blade;

FilamentView::registerRenderHook(
    PanelsRenderHook::BODY_END,
    fn (): string => Blade::render('<x-earmark adopt="#fi-main-content" side="right" />'),
);

What it stores. Earmark saves the list, not the pages. Each saved view is a path, title, favicon, position, scroll position, and timestamps. Page content is never stored.

By default the list lives in the browser tab's session storage and clears when the tab closes or the user logs out. Switch to the database store and it follows the user across devices:

php artisan vendor:publish --tag="earmark-migrations"
php artisan migrate

Signed-in users get a settings button in the panel where they choose whether saved views clear on logout (the default) or stay for next time. Guests' views last for their session and move to their account when they log in.

The endpoints run behind the web middleware, only touch the current user's or guest's own list, accept same-site paths only, and are rate limited. Schedule pruning to clear out expired guest views:

Schedule::command('model:prune', ['--model' => [\Pixelworxio\Earmark\Models\SavedView::class]])->daily();

Your own motion. A preset is a function. It receives the kind of motion (park, rise, shift, hover, dock, reveal, appear, or leave) and the panel side, and returns springs for position, width, height, and tilt:

Earmark.preset('drift', ({ kind }) => ({
    position: { stiffness: 180, damping: 22 },
    width: { stiffness: 260, damping: 24 },
    height: { stiffness: 140, damping: 18 },
    tilt: { stiffness: 200, damping: 14 },
    arc: kind === 'park' ? 0.12 : 0,
    anticipation: kind === 'park' ? -1.2 : 0,
}))

Any spring you leave out follows position. arc curves the path by that fraction of the distance, and anticipation nudges size the opposite way before it moves. Register it, then use preset="drift" on the component. Visitors who prefer reduced motion always get a short crossfade.

What you need. PHP 8.4+, Laravel 11 to 13, Livewire 4.4+, and pages navigated with wire:navigate. Earmark needs moveBefore(), so it works in Chrome and Edge 133+ and Firefox 144+. Safari doesn't have it yet, and WebKit's tracking bug is still open. Those browsers just get your normal site with no panel. Earmark is still in development, and the demo says so.

Try it

Open the demo, earmark a few pages, and watch what keeps running while you're away from them. The docs cover configuration and the JavaScript API, and the code lives at pixelworxio/earmark.

Earmark comes from the same idea as Livewire Workflows: people leave mid-task, and the software shouldn't punish them for it.

If your product has people who live in it all day, building a workspace around how they work is custom development on the TALL stack.