The @freeplaceholder/next package provides type-safe <Placeholder> and <Avatar> components built on next/image.
Installation
bash
npm install https://github.com/freeplaceholder/nextConfiguration
Add the hostname to your next.config.ts:
ts
import type { NextConfig } from "next";
const nextConfig: NextConfig = {
images: {
remotePatterns: [
{ protocol: "https", hostname: "freeplaceholder.com" },
],
},
};
export default nextConfig;Placeholder Component
Uses next/image under the hood for automatic optimization:
tsx
import { Placeholder } from "@freeplaceholder/next";
export default function Page() {
return (
<Placeholder
width={800}
height={400}
text="Hero Banner"
format="webp"
bg="3b82f6"
textColor="ffffff"
fontWeight="bold"
rounded="lg"
/>
);
}Placeholder Props
All props from the React package are supported, plus all next/image props (priority, placeholder, loading, etc.).
| Prop | Type | Description | |
|---|---|---|---|
| width | number | Image width in px (required) | |
| height | number | Image height in px (required) | |
| format | ImageFormat | Output format: svg, png, jpg, webp | |
| bg | string | Background hex color | |
| gradient | GradientDirection | to-t, to-tr, to-r, to-br, to-b, to-bl, to-l, to-tl, radial | |
| from | string | Gradient start color — hex without # | |
| via | string | Gradient middle color — hex without # | |
| to | string | Gradient end color — hex without # | |
| textColor | string | Text hex color | |
| text | string | Custom text overlay | |
| textSize | number | Font size in px | |
| textAlign | TextAlign | left, center, right | |
| textTransform | TextTransform | uppercase, lowercase, capitalize, none | |
| textDecoration | TextDecoration | underline, overline, line-through, none | |
| letterSpacing | `LetterSpacing \ | string` | Letter spacing |
| fontWeight | FontWeight | Font weight | |
| opacity | number | 0–100 | |
| grayscale | boolean | Grayscale filter | |
| blur | number | Gaussian blur 0–100 px | |
| brightness | number | 0–200 | |
| contrast | number | 0–200 | |
| hueRotate | number | 0–360 degrees | |
| invert | boolean | Invert colors | |
| saturate | number | 0–200 | |
| sepia | boolean | Sepia tone | |
| border | number | Border width in px | |
| borderColor | string | Border hex color | |
| borderStyle | BorderStyle | Border style | |
| rounded | `Rounded \ | number` | Border radius |
| lazy | boolean | Enable lazy loading with blur placeholder (default: true) |
Avatar Component
tsx
import { Avatar } from "@freeplaceholder/next";
export default function UserCard({ user }) {
return (
<Avatar
name={user.name}
size={64}
format="png"
fontWeight="bold"
grayscale
/>
);
}Avatar Props
All props from the React Avatar, plus all next/image props.
| Prop | Type | Description | |
|---|---|---|---|
| name | string | Name to derive initials from (required) | |
| size | number | Square dimensions in px (default: 128) | |
| format | ImageFormat | Output format | |
| bg | string | Background hex color | |
| gradient | GradientDirection | to-t, to-tr, to-r, to-br, to-b, to-bl, to-l, to-tl, radial | |
| from | string | Gradient start color — hex without # | |
| via | string | Gradient middle color — hex without # | |
| to | string | Gradient end color — hex without # | |
| textColor | string | Text hex color | |
| textDecoration | TextDecoration | underline, overline, line-through, none | |
| letterSpacing | `LetterSpacing \ | string` | Letter spacing |
| fontWeight | FontWeight | Font weight | |
| opacity | number | 0–100 | |
| blur | number | Gaussian blur 0–100 px | |
| brightness | number | 0–200 | |
| contrast | number | 0–200 | |
| hueRotate | number | 0–360 degrees | |
| invert | boolean | Invert colors | |
| saturate | number | 0–200 | |
| sepia | boolean | Sepia tone | |
| grayscale | boolean | Grayscale filter | |
| border | number | Border width in px | |
| borderColor | string | Border hex color | |
| borderStyle | BorderStyle | Border style | |
| rounded | `Rounded \ | number` | Border radius |
| lazy | boolean | Enable lazy loading with blur placeholder (default: true) |
URL Helpers
tsx
import { avatarUrl, placeholderUrl, snippetUrl } from "@freeplaceholder/next";
const src = placeholderUrl({ width: 1920, height: 1080, format: "webp" });
const avatar = avatarUrl({ name: "Alice", size: 96 });
const og = snippetUrl({ title: "Docs", format: "png" });App Router & Server Components
The components are marked "use client" so they work in both Server and Client components. For server-only usage, use the URL helpers directly:
tsx
import { placeholderUrl } from "@freeplaceholder/next";
export default function ServerPage() {
return <img src={placeholderUrl({ width: 600, height: 400 })} alt="Placeholder" />;
}Overriding Base URL
Add a custom base URL in your app configuration:
tsx
import { configure } from "@freeplaceholder/next";
configure({ baseUrl: "https://my-custom-instance.com" });