feat: add placeholders to docs

This commit is contained in:
Oleg Proskurin 2026-01-03 01:51:13 +07:00
parent 86528dc6cf
commit 0ebc893c33
5 changed files with 400 additions and 6 deletions

View File

@ -0,0 +1,68 @@
import type { Metadata } from 'next';
import { DocPage } from '@/components/docs/layout/DocPage';
import { JsonLd } from '@/components/seo/JsonLd';
import { createDocsMetadata, DOCS_PAGES } from '@/config/docs-seo';
import { createBreadcrumbSchema } from '@/config/docs-schema';
import { Hero } from '@/components/docs/blocks';
import Link from 'next/link';
const PAGE = DOCS_PAGES['guides'];
export const metadata: Metadata = createDocsMetadata(PAGE);
const breadcrumbSchema = createBreadcrumbSchema([
{ name: 'Home', path: '/' },
{ name: 'Documentation', path: '/docs/' },
{ name: 'Guides', path: '/docs/guides/' },
]);
export default function GuidesPage() {
return (
<>
<JsonLd data={breadcrumbSchema} />
<DocPage
breadcrumbItems={[
{ label: 'Documentation', href: '/docs/' },
{ label: 'Guides' },
]}
tocItems={[]}
nextSteps={{
links: [
{
href: '/docs/live-urls/',
title: 'Live URLs',
description: 'Generate images directly from URL parameters.',
accent: 'primary',
},
{
href: '/docs/generation/',
title: 'Image Generation',
description: 'Full control via the API.',
accent: 'secondary',
},
],
}}
>
<Hero
title="Guides"
subtitle="Step-by-step tutorials for common use cases."
/>
<section className="mb-12">
<div className="grid gap-4">
<Link
href="/docs/guides/placeholder-images/"
className="block p-6 bg-slate-800/50 border border-slate-700 rounded-lg hover:border-purple-500/50 transition-colors"
>
<h3 className="text-lg font-semibold text-white mb-2">AI Placeholder Images</h3>
<p className="text-gray-400 text-sm">
Generate contextual placeholder images for development.
Replace gray boxes with AI visuals that match your design.
</p>
</Link>
</div>
</section>
</DocPage>
</>
);
}

View File

@ -0,0 +1,245 @@
import type { Metadata } from 'next';
import { TipBox } from '@/components/docs/shared/TipBox';
import { Table } from '@/components/docs/shared/Table';
import { CodeBlock } from '@/components/docs/shared/CodeBlock';
import { DocPage } from '@/components/docs/layout/DocPage';
import { JsonLd } from '@/components/seo/JsonLd';
import { createDocsMetadata, DOCS_PAGES } from '@/config/docs-seo';
import { createBreadcrumbSchema, createTechArticleSchema } from '@/config/docs-schema';
import { Hero, SectionHeader, InlineCode } from '@/components/docs/blocks';
const PAGE = DOCS_PAGES['guide-placeholder-images'];
export const metadata: Metadata = createDocsMetadata(PAGE);
const breadcrumbSchema = createBreadcrumbSchema([
{ name: 'Home', path: '/' },
{ name: 'Documentation', path: '/docs/' },
{ name: 'Guides', path: '/docs/guides/' },
{ name: 'Placeholder Images', path: '/docs/guides/placeholder-images/' },
]);
const articleSchema = createTechArticleSchema(PAGE);
const tocItems = [
{ id: 'why-ai-placeholders', text: 'Why AI Placeholders?', level: 2 },
{ id: 'quick-start', text: 'Quick Start', level: 2 },
{ id: 'common-sizes', text: 'Common Sizes', level: 2 },
{ id: 'dark-mode', text: 'Dark Mode Placeholders', level: 2 },
{ id: 'profile-avatars', text: 'Profile Avatars', level: 2 },
{ id: 'tips', text: 'Tips for Better Results', level: 2 },
{ id: 'next-steps', text: 'Next Steps', level: 2 },
];
export default function PlaceholderImagesGuidePage() {
return (
<>
<JsonLd data={breadcrumbSchema} />
<JsonLd data={articleSchema} />
<DocPage
breadcrumbItems={[
{ label: 'Documentation', href: '/docs/' },
{ label: 'Guides', href: '/docs/guides/' },
{ label: 'Placeholder Images' },
]}
tocItems={tocItems}
nextSteps={{
links: [
{
href: '/docs/live-urls/',
title: 'Live URLs',
description: 'Full documentation on URL-based generation.',
accent: 'primary',
},
{
href: '/docs/generation/',
title: 'Image Generation',
description: 'Advanced generation with the API.',
accent: 'secondary',
},
],
}}
>
<Hero
title="AI Placeholder Images"
subtitle="Generate contextual placeholder images that match your design. Not gray boxes. Not random stock photos."
/>
<section id="why-ai-placeholders" className="mb-12">
<SectionHeader level={2} id="why-ai-placeholders">
Why AI Placeholders?
</SectionHeader>
<p className="text-gray-300 leading-relaxed mb-4">
Traditional placeholder services give you gray rectangles or random photos
that have nothing to do with your actual content.
</p>
<p className="text-gray-300 leading-relaxed mb-6">
With Banatie Live URLs, you describe what you need and get a relevant AI-generated image instantly.
Your mockups look real. Client demos make sense. Prototypes feel complete.
</p>
<Table
headers={['Service', 'What You Get']}
rows={[
['placehold.co', 'Gray box with dimensions text'],
['picsum.photos', 'Random landscape or portrait'],
['Banatie', 'AI image matching your description'],
]}
/>
</section>
<section id="quick-start" className="mb-12">
<SectionHeader level={2} id="quick-start">
Quick Start
</SectionHeader>
<p className="text-gray-300 leading-relaxed mb-6">
Use a Live URL directly in your <InlineCode>&lt;img&gt;</InlineCode> tag:
</p>
<CodeBlock
code={`<img
src="https://cdn.banatie.app/{org}/{project}/live/demo?prompt=modern+coffee+shop+interior"
alt="Coffee shop"
/>`}
language="html"
filename="Basic Usage"
/>
<p className="text-gray-300 leading-relaxed mt-6">
First request generates the image. Subsequent requests serve from cache instantly.
</p>
</section>
<section id="common-sizes" className="mb-12">
<SectionHeader level={2} id="common-sizes">
Common Sizes
</SectionHeader>
<p className="text-gray-300 leading-relaxed mb-6">
Use the <InlineCode>aspectRatio</InlineCode> parameter for standard sizes:
</p>
<Table
headers={['Use Case', 'Aspect Ratio', 'Example Dimensions']}
rows={[
['Avatar / Profile', '1:1', '200x200, 400x400'],
['Thumbnail', '3:2', '300x200, 600x400'],
['Card Image', '4:3', '400x300, 800x600'],
['Hero / Banner', '16:9', '1200x675, 1920x1080'],
['OG Image', '1200:630', '1200x630'],
['Product Square', '1:1', '600x600, 800x800'],
]}
/>
<CodeBlock
code={`<!-- Square avatar -->
<img src="...?prompt=professional+headshot&aspectRatio=1:1" />
<!-- Wide hero banner -->
<img src="...?prompt=abstract+tech+background&aspectRatio=16:9" />
<!-- OG image for social -->
<img src="...?prompt=blog+post+cover&aspectRatio=1200:630" />`}
language="html"
filename="Size Examples"
/>
</section>
<section id="dark-mode" className="mb-12">
<SectionHeader level={2} id="dark-mode">
Dark Mode Placeholders
</SectionHeader>
<p className="text-gray-300 leading-relaxed mb-6">
For dark UI interfaces, include dark theme hints in your prompt:
</p>
<CodeBlock
code={`<!-- Dark mode card background -->
<img src="...?prompt=abstract+dark+gradient+background+for+dark+theme+ui" />
<!-- Dark mode product shot -->
<img src="...?prompt=smartphone+on+dark+surface+moody+lighting" />
<!-- Dark mode avatar placeholder -->
<img src="...?prompt=silhouette+avatar+dark+background&aspectRatio=1:1" />`}
language="html"
filename="Dark Mode Examples"
/>
<div className="mt-6">
<TipBox variant="compact" type="info">
Keywords like "dark background", "moody lighting", "dark theme", and "night mode" help generate dark-friendly images.
</TipBox>
</div>
</section>
<section id="profile-avatars" className="mb-12">
<SectionHeader level={2} id="profile-avatars">
Profile Avatars
</SectionHeader>
<p className="text-gray-300 leading-relaxed mb-6">
Generate realistic avatar placeholders for user profiles:
</p>
<CodeBlock
code={`<!-- Generic professional avatar -->
<img src="...?prompt=professional+headshot+neutral+background&aspectRatio=1:1" />
<!-- Diverse team avatars -->
<img src="...?prompt=young+professional+woman+headshot&aspectRatio=1:1" />
<img src="...?prompt=middle+aged+man+business+portrait&aspectRatio=1:1" />
<!-- Stylized/illustrated avatars -->
<img src="...?prompt=minimal+geometric+avatar+illustration&aspectRatio=1:1" />`}
language="html"
filename="Avatar Examples"
/>
</section>
<section id="tips" className="mb-12">
<SectionHeader level={2} id="tips">
Tips for Better Results
</SectionHeader>
<ul className="space-y-4 text-gray-300">
<li className="flex items-start gap-3">
<span className="text-purple-400 mt-1"></span>
<div>
<strong className="text-white">Be specific</strong>
<p className="text-gray-400 text-sm mt-1">
"modern minimalist office with plants" works better than "office".
</p>
</div>
</li>
<li className="flex items-start gap-3">
<span className="text-purple-400 mt-1"></span>
<div>
<strong className="text-white">Include style hints</strong>
<p className="text-gray-400 text-sm mt-1">
Add "photorealistic", "illustration", "3D render", or "flat design" for consistent style.
</p>
</div>
</li>
<li className="flex items-start gap-3">
<span className="text-purple-400 mt-1"></span>
<div>
<strong className="text-white">Use scopes to organize</strong>
<p className="text-gray-400 text-sm mt-1">
Group related placeholders: /live/avatars/, /live/products/, /live/backgrounds/.
</p>
</div>
</li>
<li className="flex items-start gap-3">
<span className="text-purple-400 mt-1"></span>
<div>
<strong className="text-white">Same prompt = same image</strong>
<p className="text-gray-400 text-sm mt-1">
Cached results mean consistent placeholders across your app.
</p>
</div>
</li>
</ul>
</section>
</DocPage>
</>
);
}

View File

@ -28,6 +28,7 @@ const tocItems = [
{ id: 'the-concept', text: 'The Concept', level: 2 }, { id: 'the-concept', text: 'The Concept', level: 2 },
{ id: 'url-format', text: 'URL Format', level: 2 }, { id: 'url-format', text: 'URL Format', level: 2 },
{ id: 'try-it', text: 'Try It', level: 2 }, { id: 'try-it', text: 'Try It', level: 2 },
{ id: 'placeholder-images', text: 'Placeholder Images', level: 2 },
{ id: 'caching-behavior', text: 'Caching Behavior', level: 2 }, { id: 'caching-behavior', text: 'Caching Behavior', level: 2 },
{ id: 'scopes', text: 'Scopes', level: 2 }, { id: 'scopes', text: 'Scopes', level: 2 },
{ id: 'rate-limits', text: 'Rate Limits', level: 2 }, { id: 'rate-limits', text: 'Rate Limits', level: 2 },
@ -65,7 +66,7 @@ export default function LiveUrlsPage() {
> >
<Hero <Hero
title="Live URLs" title="Live URLs"
subtitle="Generate images directly from URL parameters. No API calls needed — just use the URL in your HTML." subtitle="Generate AI placeholder images and dynamic visuals directly from URL. No API calls — just use the URL in your HTML."
/> />
<section id="the-concept" className="mb-12"> <section id="the-concept" className="mb-12">
@ -150,6 +151,41 @@ export default function LiveUrlsPage() {
/> />
</section> </section>
<section id="placeholder-images" className="mb-12">
<SectionHeader level={2} id="placeholder-images">
Placeholder Images
</SectionHeader>
<p className="text-gray-300 leading-relaxed mb-6">
Live URLs are perfect for generating AI placeholder images during development.
Unlike generic placeholder services that show gray boxes or random stock photos,
Banatie generates contextual images that match your design intent.
</p>
<p className="text-gray-400 text-sm mb-4">Common placeholder sizes:</p>
<CodeBlock
code={`<!-- Avatar placeholder (200×200) -->
<img src="https://cdn.banatie.app/.../live/avatars?prompt=professional+headshot&aspectRatio=1:1" />
<!-- Thumbnail placeholder (300×200) -->
<img src="https://cdn.banatie.app/.../live/thumbs?prompt=product+photo&aspectRatio=3:2" />
<!-- Hero placeholder (1200×630) -->
<img src="https://cdn.banatie.app/.../live/hero?prompt=modern+office+interior&aspectRatio=1200:630" />
<!-- Card image placeholder (400×300) -->
<img src="https://cdn.banatie.app/.../live/cards?prompt=abstract+gradient+background&aspectRatio=4:3" />`}
language="html"
filename="Placeholder Examples"
/>
<div className="mt-6">
<TipBox variant="compact" type="info">
For dark mode interfaces, include "dark theme" or "dark background" in your prompt.
</TipBox>
</div>
</section>
<section id="caching-behavior" className="mb-12"> <section id="caching-behavior" className="mb-12">
<SectionHeader level={2} id="caching-behavior"> <SectionHeader level={2} id="caching-behavior">
Caching Behavior Caching Behavior
@ -243,8 +279,11 @@ https://cdn.banatie.app/my-org/my-project/live/blog-images?prompt=...`}
<li className="flex items-start gap-3"> <li className="flex items-start gap-3">
<span className="text-purple-400 mt-1"></span> <span className="text-purple-400 mt-1"></span>
<div> <div>
<strong className="text-white">Dynamic placeholders</strong> <strong className="text-white">AI Placeholder Images</strong>
<p className="text-gray-400 text-sm mt-1">Generate placeholder images during development that match your design intent.</p> <p className="text-gray-400 text-sm mt-1">
Replace gray boxes and random stock photos with contextual AI images.
Perfect for prototypes, client demos, and design mockups.
</p>
</div> </div>
</li> </li>
<li className="flex items-start gap-3"> <li className="flex items-start gap-3">

View File

@ -72,5 +72,18 @@ export default function sitemap(): MetadataRoute.Sitemap {
changeFrequency: 'weekly', changeFrequency: 'weekly',
priority: 0.7, priority: 0.7,
}, },
// Documentation - Guides
{
url: `${baseUrl}/docs/guides/`,
lastModified: new Date(),
changeFrequency: 'weekly',
priority: 0.8,
},
{
url: `${baseUrl}/docs/guides/placeholder-images/`,
lastModified: new Date(),
changeFrequency: 'weekly',
priority: 0.8,
},
]; ];
} }

View File

@ -75,10 +75,18 @@ export const DOCS_PAGES = {
}, },
'live-urls': { 'live-urls': {
path: '/docs/live-urls/', path: '/docs/live-urls/',
title: 'Live URLs — Generate Images from URL | Banatie API Docs', title: 'Live URLs — AI Placeholder Images & Dynamic Generation | Banatie',
description: description:
'Generate images directly from URL parameters. No API calls needed — use the URL in img tags. Automatic caching.', 'Generate AI placeholder images directly from URL. No API calls — use in img tags. Perfect for prototypes, mockups, and dynamic content.',
keywords: ['live url image generation', 'url to image', 'dynamic image generation', 'image from url', 'cached image api'], keywords: [
'placeholder images',
'placeholder image url',
'ai placeholder generator',
'live url image generation',
'dynamic image generation',
'image placeholder api',
'placeholder image api',
],
}, },
authentication: { authentication: {
path: '/docs/authentication/', path: '/docs/authentication/',
@ -116,4 +124,25 @@ export const DOCS_PAGES = {
description: 'Manage live URL scopes. Create, configure, and control live image generation endpoints.', description: 'Manage live URL scopes. Create, configure, and control live image generation endpoints.',
keywords: ['live scopes api', 'live url management', 'scope limits', 'live generation api'], keywords: ['live scopes api', 'live url management', 'scope limits', 'live generation api'],
}, },
'guides': {
path: '/docs/guides/',
title: 'Guides | Banatie Docs',
description: 'Step-by-step guides for common use cases. Placeholder images, prototyping, and more.',
keywords: ['banatie guides', 'image generation tutorials', 'api guides'],
},
'guide-placeholder-images': {
path: '/docs/guides/placeholder-images/',
title: 'AI Placeholder Images Guide | Banatie',
description:
'Generate AI placeholder images for development. Replace gray boxes with contextual visuals. Sizes for avatars, thumbnails, heroes, and more.',
keywords: [
'placeholder images',
'ai placeholder generator',
'placeholder image api',
'image placeholder dark',
'profile placeholder image',
'placeholder image url',
'dummy image generator',
],
},
} as const satisfies Record<string, DocsPageSeo>; } as const satisfies Record<string, DocsPageSeo>;