Img — Sample
A runnable gallery using the built-in <Img> component: an eager hero banner, a blurred placeholder, and lazily-loaded photos.
Sample
Server component
A page that mixes an eager above-the-fold hero with a grid of lazily-loaded photos and one blurred placeholder. None of this needs a "use client" directive —<Img> handles hydration internally.
app/pages/gallery.tsxtypescript
import { Img } from 'nukejs'
const photos = [
{ src: '/photos/lake.jpg', alt: 'Still lake at dusk' },
{ src: '/photos/forest.jpg', alt: 'Pine forest in fog' },
{ src: '/photos/desert.jpg', alt: 'Dunes at golden hour' },
{ src: '/photos/city.jpg', alt: 'City skyline at night' },
]
export default function Gallery() {
return (
<main>
{/* Above-the-fold: load immediately */}
<Img
src="/photos/hero.jpg"
alt="Welcome to the gallery"
width={1600}
height={600}
eager
className="hero"
/>
<h1>Gallery</h1>
<div className="grid">
{photos.map(p => (
<Img
key={p.src}
src={p.src}
alt={p.alt}
width={400}
height={300}
placeholder={`${p.src.replace('.jpg', '')}-tiny.jpg`}
/>
))}
</div>
</main>
)
}Default export only
As with every page, this file exports a single default component. The component can beasync and fetch the photo list from a database — <Img> works exactly the same in an async server component:
app/pages/gallery.tsxtypescript
import { Img } from 'nukejs'
export default async function Gallery() {
const photos = await db.photos.findMany()
return (
<div className="grid">
{photos.map(p => (
<Img key={p.id} src={p.url} alt={p.alt} width={400} height={300} />
))}
</div>
)
}Styling notes
Pass className and style like a normal <img>. The internal blur transition is merged with your inline style, so don't setfilter or opacity directly unless you want to override the placeholder fade.
app/public/gallery.csstypescript
.hero { object-fit: cover; border-radius: 12px; }
.grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
gap: 16px;
}
.grid img { width: 100%; height: auto; border-radius: 8px; }Always set width & height Providing both reserves space in the document immediately, so lazy-loaded images never cause layout shift when they swap in.