@peekjs/core
v0.3.4
Published
Framework-agnostic live page previews on link hover
Maintainers
Readme
@peekjs/core
Vanilla JS link-hover previews. Same-origin links get a true live iframe — zero config, zero server. Cross-origin links fall back to a metadata card.
Install
npm install @peekjs/coreQuick start
import { init } from '@peekjs/core';
init({ selector: 'a[data-peek]' });<!-- Same-origin: live iframe preview, no server needed -->
<a href="/docs/getting-started" data-peek>Getting started</a>
<!-- Cross-origin: OG metadata card -->
<a href="https://github.com/ayangabryl/peekjs" data-peek>GitHub</a>What works where
| Link type | What you get | Server needed? |
|---|---|---|
| Same-origin | Live iframe | No |
| Known embed (YouTube, CodePen…) | Embed iframe | No |
| Image URL | <img> preview | No |
| Cross-origin (framing allowed) | Live iframe | No |
| Cross-origin (framing blocked) | OG metadata card | Optional proxy |
The same-origin case is Peek's sweet spot — docs, wikis, app navigation, blogs all work with zero configuration.
Options
init({
selector: 'a[data-peek]', // CSS selector
delay: 300, // ms before showing
hideDelay: 150, // ms before hiding
render: 'auto', // 'auto' | 'iframe' | 'shadow' | 'card' | 'tooltip' | 'image'
placement: 'auto', // 'auto' | 'top' | 'bottom' | 'left' | 'right' | …
maxWidth: 340,
maxHeight: 220,
size: 'md', // 'sm' | 'md' | 'lg' | 'xl' — sets maxWidth/maxHeight together
theme: 'auto', // 'auto' | 'light' | 'dark'
trigger: 'hover', // 'hover' | 'click' | 'focus'
display: 'float', // 'float' | 'inline'
animationDuration: 160,
loadTimeout: 5000, // ms before falling back to next renderer
cacheTTL: 300_000, // ms to keep fetched metadata (0 = forever)
followCursor: false,
skeleton: true,
transition: true, // View Transitions morph on click
corsProxy: 'https://my-worker.example.com/?url={{url}}', // optional
onRender(link, mode) {}, // which renderer actually ran
onFallback(link, chain) {}, // full fallback chain log
onShow(link, preview) {},
onHide(link) {},
onError(link, err) {},
});Per-link attributes
<a href="…" data-peek
data-peek-size="lg"
data-peek-src="https://other-url.com"
data-peek-display="inline"
data-peek-follow-cursor="true"
data-peek-flip="false"
data-peek-group="nav"
data-peek-title="Custom title"
data-peek-image="https://…/og.png"
>Link</a>CORS proxy
Cross-origin previews that need the CORS proxy send your users' URLs to a third-party server. For production, self-host a worker that strips X-Frame-Options and CORS headers:
init({
corsProxy: 'https://proxy.example.com/?url={{url}}',
});A hosted fallback (proxy.peekjs.dev) is used when no custom proxy is set.
