doc: updates to live urls

This commit is contained in:
Oleg Proskurin 2026-01-04 15:04:26 +07:00
parent 1aa307aac9
commit 9b032eaf5a
3 changed files with 332 additions and 273 deletions

View File

@ -6,11 +6,7 @@ import { DocPage } from '@/components/docs/layout/DocPage';
import { JsonLd } from '@/components/seo/JsonLd'; import { JsonLd } from '@/components/seo/JsonLd';
import { createDocsMetadata, DOCS_PAGES } from '@/config/docs-seo'; import { createDocsMetadata, DOCS_PAGES } from '@/config/docs-seo';
import { createBreadcrumbSchema, createTechArticleSchema } from '@/config/docs-schema'; import { createBreadcrumbSchema, createTechArticleSchema } from '@/config/docs-schema';
import { import { Hero, SectionHeader, InlineCode } from '@/components/docs/blocks';
Hero,
SectionHeader,
InlineCode,
} from '@/components/docs/blocks';
const PAGE = DOCS_PAGES['live-urls']; const PAGE = DOCS_PAGES['live-urls'];
@ -42,129 +38,276 @@ export default function LiveUrlsPage() {
<JsonLd data={breadcrumbSchema} /> <JsonLd data={breadcrumbSchema} />
<JsonLd data={articleSchema} /> <JsonLd data={articleSchema} />
<DocPage <DocPage
breadcrumbItems={[ breadcrumbItems={[{ label: 'Documentation', href: '/docs/' }, { label: 'Live URLs' }]}
{ label: 'Documentation', href: '/docs/' }, tocItems={tocItems}
{ label: 'Live URLs' }, nextSteps={{
]} links: [
tocItems={tocItems} {
nextSteps={{ href: '/docs/api/live-scopes/',
links: [ title: 'API Reference: Live Scopes',
{ description: 'Manage scopes and generation limits.',
href: '/docs/api/live-scopes/', accent: 'primary',
title: 'API Reference: Live Scopes', },
description: 'Manage scopes and generation limits.', {
accent: 'primary', href: '/docs/generation/',
}, title: 'Image Generation',
{ description: 'Full control via the generations API.',
href: '/docs/generation/', accent: 'secondary',
title: 'Image Generation', },
description: 'Full control via the generations API.', ],
accent: 'secondary', }}
}, >
], <Hero
}} title="Live URLs"
> subtitle="Generate images directly from URL parameters. No API calls needed — just use the URL in your HTML."
<Hero
title="Live URLs"
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">
<SectionHeader level={2} id="the-concept">
The Concept
</SectionHeader>
<p className="text-gray-300 leading-relaxed mb-4">
Put your prompt in a URL. Use it directly in an <InlineCode>&lt;img src="..."&gt;</InlineCode> tag.
</p>
<p className="text-gray-300 leading-relaxed">
First request generates the image. All subsequent requests serve it from cache instantly.
</p>
</section>
<section id="url-format" className="mb-12">
<SectionHeader level={2} id="url-format">
URL Format
</SectionHeader>
<CodeBlock
code={`https://cdn.banatie.app/{org}/{project}/live/{scope}?prompt=...&aspectRatio=...`}
language="text"
filename="Live URL Format"
/> />
<p className="text-gray-300 leading-relaxed mt-6 mb-4"> <section id="the-concept" className="mb-12">
Query parameters: <SectionHeader level={2} id="the-concept">
</p> The Concept
</SectionHeader>
<p className="text-gray-300 leading-relaxed mb-4">
Put your prompt in a URL. Use it directly in an{' '}
<InlineCode>&lt;img src="..."&gt;</InlineCode> tag.
</p>
<p className="text-gray-300 leading-relaxed">
First request generates the image. All subsequent requests serve it from cache
instantly.
</p>
</section>
<Table <section id="url-format" className="mb-12">
headers={['Parameter', 'Required', 'Description']} <SectionHeader level={2} id="url-format">
rows={[ URL Format
[ </SectionHeader>
<InlineCode key="p">prompt</InlineCode>,
<span key="r" className="text-green-400">Yes</span>,
'Text description of the image to generate',
],
[
<InlineCode key="p">aspectRatio</InlineCode>,
<span key="r" className="text-gray-500">No</span>,
'Image ratio: 1:1, 16:9, 9:16, 3:2 (default: 16:9)',
],
[
<InlineCode key="p">autoEnhance</InlineCode>,
<span key="r" className="text-gray-500">No</span>,
'Enable prompt enhancement (default: true)',
],
[
<InlineCode key="p">template</InlineCode>,
<span key="r" className="text-gray-500">No</span>,
'Enhancement template to use',
],
]}
/>
</section>
<section id="try-it" className="mb-12"> <CodeBlock
<SectionHeader level={2} id="try-it"> code={`https://cdn.banatie.app/{org}/{project}/live/{scope}?prompt=...&aspectRatio=...`}
Try It language="text"
</SectionHeader> filename="Live URL Format"
<p className="text-gray-300 leading-relaxed mb-6"> />
Open this URL in your browser:
</p>
<CodeBlock <p className="text-gray-300 leading-relaxed mt-6 mb-4">Query parameters:</p>
code={`https://cdn.banatie.app/my-org/my-project/live/demo?prompt=a+friendly+robot+waving+hello&aspectRatio=16:9`}
language="text"
filename="Example Live URL"
/>
<p className="text-gray-300 leading-relaxed mt-6 mb-4"> <Table
Or use it directly in HTML: headers={['Parameter', 'Required', 'Description']}
</p> rows={[
[
<InlineCode key="p">prompt</InlineCode>,
<span key="r" className="text-green-400">
Yes
</span>,
'Text description of the image to generate',
],
[
<InlineCode key="p">aspectRatio</InlineCode>,
<span key="r" className="text-gray-500">
No
</span>,
'Image ratio: 1:1, 16:9, 9:16, 3:2 (default: 16:9)',
],
[
<InlineCode key="p">template</InlineCode>,
<span key="r" className="text-gray-500">
No
</span>,
'Enhancement template to use',
],
[
<InlineCode key="p">autoEnhance</InlineCode>,
<span key="r" className="text-gray-500">
No
</span>,
'Enable prompt enhancement (default: true)',
],
]}
/>
</section>
<CodeBlock <section id="try-it" className="mb-12">
code={`<img <SectionHeader level={2} id="try-it">
Try It
</SectionHeader>
<p className="text-gray-300 leading-relaxed mb-6">Open this URL in your browser:</p>
<CodeBlock
code={`https://cdn.banatie.app/my-org/my-project/live/demo?prompt=a+friendly+robot+waving+hello&aspectRatio=16:9`}
language="text"
filename="Example Live URL"
/>
<p className="text-gray-300 leading-relaxed mt-6 mb-4">Or use it directly in HTML:</p>
<CodeBlock
code={`<img
src="https://cdn.banatie.app/my-org/my-project/live/hero?prompt=mountain+landscape+at+sunset&aspectRatio=16:9" src="https://cdn.banatie.app/my-org/my-project/live/hero?prompt=mountain+landscape+at+sunset&aspectRatio=16:9"
alt="Mountain landscape" alt="Mountain landscape"
/>`} />`}
language="html" language="html"
filename="HTML Usage" filename="HTML Usage"
/> />
</section> </section>
<section id="placeholder-images" className="mb-12"> <section id="caching-behavior" className="mb-12">
<SectionHeader level={2} id="placeholder-images"> <SectionHeader level={2} id="caching-behavior">
Placeholder Images Caching Behavior
</SectionHeader> </SectionHeader>
<p className="text-gray-300 leading-relaxed mb-6"> <p className="text-gray-300 leading-relaxed mb-6">
Live URLs are perfect for generating AI placeholder images during development. The response includes an <InlineCode>X-Cache-Status</InlineCode> header:
Unlike generic placeholder services that show gray boxes or random stock photos, </p>
Banatie generates contextual images that match your design intent.
</p>
<p className="text-gray-400 text-sm mb-4">Common placeholder sizes:</p> <Table
headers={['Status', 'Meaning', 'Response Time']}
rows={[
[
<InlineCode key="s" color="success">
HIT
</InlineCode>,
'Image served from cache',
'Instant (milliseconds)',
],
[<InlineCode key="s">MISS</InlineCode>, 'New image generated', 'A few seconds'],
]}
/>
<CodeBlock <p className="text-gray-300 leading-relaxed mt-6">
code={`<!-- Avatar placeholder (200×200) --> Cache hits are unlimited and don't count toward rate limits. Only new generations (cache
MISS) are rate limited.
</p>
</section>
<section id="scopes" className="mb-12">
<SectionHeader level={2} id="scopes">
Scopes
</SectionHeader>
<p className="text-gray-300 leading-relaxed mb-6">
Scopes organize your live generations. Each scope has its own generation limit.
</p>
<CodeBlock
code={`# Different scopes for different purposes
https://cdn.banatie.app/my-org/my-project/live/hero-section?prompt=...
https://cdn.banatie.app/my-org/my-project/live/product-gallery?prompt=...
https://cdn.banatie.app/my-org/my-project/live/blog-images?prompt=...`}
language="text"
filename="Scope Examples"
/>
<p className="text-gray-300 leading-relaxed mt-6">
Scopes are auto-created on first use. You can also pre-configure them via the API to set
custom limits.
</p>
</section>
{/* <section id="rate-limits" className="mb-12">
<SectionHeader level={2} id="rate-limits">
Rate Limits
</SectionHeader>
<Table
headers={['Limit Type', 'Value', 'Notes']}
rows={[
[
'Per IP',
<span key="v" className="text-amber-400">
10 new generations/hour
</span>,
'Only applies to cache MISS',
],
[
'Per Scope',
<span key="v" className="text-amber-400">
30 generations
</span>,
'Configurable via API',
],
[
'Cache Hits',
<span key="v" className="text-green-400">
Unlimited
</span>,
'No limits on cached images',
],
]}
/>
<div className="mt-6">
<TipBox variant="compact" type="info">
Rate limits protect the service from abuse. For high-volume needs, use the generations
API directly.
</TipBox>
</div>
</section> */}
<section id="use-cases" className="mb-12">
<SectionHeader level={2} id="use-cases">
Use Cases
</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">Static HTML & serverless sites</strong>
<p className="text-gray-400 text-sm mt-1">
Deploy HTML pages without configuring asset hosting or CDN infrastructure. Images
are served directly from Banatie's edge network.
</p>
</div>
</li>
<li className="flex items-start gap-3">
<span className="text-purple-400 mt-1"></span>
<div>
<strong className="text-white">AI-assisted development</strong>
<p className="text-gray-400 text-sm mt-1">
Enable AI coding assistants to generate complete HTML or JSX with contextual
images in a single passno asset pipeline required.
</p>
</div>
</li>
<li className="flex items-start gap-3">
<span className="text-purple-400 mt-1"></span>
<div>
<strong className="text-white">Rapid prototyping</strong>
<p className="text-gray-400 text-sm mt-1">
Test different visuals without writing backend code.
</p>
</div>
</li>
<li className="flex items-start gap-3">
<span className="text-purple-400 mt-1"></span>
<div>
<strong className="text-white">AI placeholder images</strong>
<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>
</li>
<li className="flex items-start gap-3">
<span className="text-purple-400 mt-1"></span>
<div>
<strong className="text-white">Personalized content</strong>
<p className="text-gray-400 text-sm mt-1">
Generate unique images based on user data or preferences for dynamic,
individualized experiences.
</p>
</div>
</li>
</ul>
</section>
<section id="placeholder-images" className="mb-12">
<TipBox variant="protip">
Use Live URLs as intelligent placeholder images during development. Generate contextual
visuals that match your design intentno more gray boxes or random stock photos.
</TipBox>
<p className="text-gray-400 text-sm mt-6 mb-4">Common placeholder configurations:</p>
<CodeBlock
code={`<!-- Avatar placeholder (200×200) -->
<img src="https://cdn.banatie.app/.../live/avatars?prompt=professional+headshot&aspectRatio=1:1" /> <img src="https://cdn.banatie.app/.../live/avatars?prompt=professional+headshot&aspectRatio=1:1" />
<!-- Thumbnail placeholder (300×200) --> <!-- Thumbnail placeholder (300×200) -->
@ -175,141 +318,18 @@ export default function LiveUrlsPage() {
<!-- Card image placeholder (400×300) --> <!-- Card image placeholder (400×300) -->
<img src="https://cdn.banatie.app/.../live/cards?prompt=abstract+gradient+background&aspectRatio=4:3" />`} <img src="https://cdn.banatie.app/.../live/cards?prompt=abstract+gradient+background&aspectRatio=4:3" />`}
language="html" language="html"
filename="Placeholder Examples" filename="Placeholder Examples"
/> />
<div className="mt-6"> <div className="mt-6">
<TipBox variant="compact" type="info"> <TipBox variant="compact" type="info">
For dark mode interfaces, include "dark theme" or "dark background" in your prompt. For dark mode interfaces, include "dark theme" or "dark background" in your prompt.
</TipBox> </TipBox>
</div> </div>
</section> </section>
<section id="caching-behavior" className="mb-12"> </DocPage>
<SectionHeader level={2} id="caching-behavior">
Caching Behavior
</SectionHeader>
<p className="text-gray-300 leading-relaxed mb-6">
The response includes an <InlineCode>X-Cache-Status</InlineCode> header:
</p>
<Table
headers={['Status', 'Meaning', 'Response Time']}
rows={[
[
<InlineCode key="s" color="success">HIT</InlineCode>,
'Image served from cache',
'Instant (milliseconds)',
],
[
<InlineCode key="s">MISS</InlineCode>,
'New image generated',
'A few seconds',
],
]}
/>
<p className="text-gray-300 leading-relaxed mt-6">
Cache hits are unlimited and don't count toward rate limits. Only new generations (cache MISS) are rate limited.
</p>
</section>
<section id="scopes" className="mb-12">
<SectionHeader level={2} id="scopes">
Scopes
</SectionHeader>
<p className="text-gray-300 leading-relaxed mb-6">
Scopes organize your live generations. Each scope has its own generation limit.
</p>
<CodeBlock
code={`# Different scopes for different purposes
https://cdn.banatie.app/my-org/my-project/live/hero-section?prompt=...
https://cdn.banatie.app/my-org/my-project/live/product-gallery?prompt=...
https://cdn.banatie.app/my-org/my-project/live/blog-images?prompt=...`}
language="text"
filename="Scope Examples"
/>
<p className="text-gray-300 leading-relaxed mt-6">
Scopes are auto-created on first use. You can also pre-configure them via the API to set custom limits.
</p>
</section>
<section id="rate-limits" className="mb-12">
<SectionHeader level={2} id="rate-limits">
Rate Limits
</SectionHeader>
<Table
headers={['Limit Type', 'Value', 'Notes']}
rows={[
[
'Per IP',
<span key="v" className="text-amber-400">10 new generations/hour</span>,
'Only applies to cache MISS',
],
[
'Per Scope',
<span key="v" className="text-amber-400">30 generations</span>,
'Configurable via API',
],
[
'Cache Hits',
<span key="v" className="text-green-400">Unlimited</span>,
'No limits on cached images',
],
]}
/>
<div className="mt-6">
<TipBox variant="compact" type="info">
Rate limits protect the service from abuse. For high-volume needs, use the generations API directly.
</TipBox>
</div>
</section>
<section id="use-cases" className="mb-12">
<SectionHeader level={2} id="use-cases">
Use Cases
</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">AI Placeholder Images</strong>
<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>
</li>
<li className="flex items-start gap-3">
<span className="text-purple-400 mt-1"></span>
<div>
<strong className="text-white">Personalized content</strong>
<p className="text-gray-400 text-sm mt-1">Create unique images based on user data or preferences.</p>
</div>
</li>
<li className="flex items-start gap-3">
<span className="text-purple-400 mt-1"></span>
<div>
<strong className="text-white">Rapid prototyping</strong>
<p className="text-gray-400 text-sm mt-1">Test different visuals without writing backend code.</p>
</div>
</li>
<li className="flex items-start gap-3">
<span className="text-purple-400 mt-1"></span>
<div>
<strong className="text-white">HTML emails</strong>
<p className="text-gray-400 text-sm mt-1">Include dynamic images in email templates with just a URL.</p>
</div>
</li>
</ul>
</section>
</DocPage>
</> </>
); );
} }

View File

@ -58,6 +58,13 @@ const navigationItems: NavItem[] = [
label: 'Authentication', label: 'Authentication',
href: '/docs/authentication/', href: '/docs/authentication/',
}, },
{
label: 'Guides',
href: '/docs/guides/',
children: [
{ label: 'Image Placeholders', href: '/docs/guides/placeholder-images/' },
],
},
{ {
label: 'API Reference', label: 'API Reference',
href: '/docs/api/', href: '/docs/api/',
@ -69,13 +76,7 @@ const navigationItems: NavItem[] = [
{ label: 'Live Scopes', href: '/docs/api/live-scopes/' }, { label: 'Live Scopes', href: '/docs/api/live-scopes/' },
], ],
}, },
{
label: 'Guides',
href: '/docs/guides/',
children: [
{ label: 'Image Placeholders', href: '/docs/guides/placeholder-images/' },
],
},
]; ];
export const DocsSidebar = ({ currentPath }: DocsSidebarProps) => { export const DocsSidebar = ({ currentPath }: DocsSidebarProps) => {

View File

@ -1,18 +1,20 @@
'use client'; 'use client';
import { Sparkles, Lightbulb, AlertTriangle, CheckCircle } from 'lucide-react';
/** /**
* TipBox Component - Dual Style System * TipBox Component - Multi-Style Callout System
* *
* Provides two distinct styles for callouts/notes: * Provides three distinct styles for callouts/notes:
* *
* 1. Compact Style (Variant A inspired): * 1. Compact Style:
* - Small emoji icon on left * - Lucide icon on left
* - Compact padding (p-4) * - Compact padding (p-4)
* - Smaller text (text-sm) * - Smaller text (text-sm)
* - Subtle background with thin border * - Subtle background with thin border
* - Best for minor notes and tips * - Best for minor notes and tips
* *
* 2. Prominent Style (Adapted from Variant C): * 2. Prominent Style:
* - NO icon * - NO icon
* - Larger padding (p-6) * - Larger padding (p-6)
* - Larger text (text-base) * - Larger text (text-base)
@ -20,6 +22,12 @@
* - More visual weight * - More visual weight
* - Best for important warnings and security notices * - Best for important warnings and security notices
* *
* 3. Protip Style:
* - Sparkles icon with "Pro Tip" label
* - Golden/amber color scheme
* - Premium visual treatment with glow
* - Best for highlighting valuable tips and tricks
*
* Usage: * Usage:
* <TipBox variant="compact" type="info"> * <TipBox variant="compact" type="info">
* This is a compact tip * This is a compact tip
@ -28,10 +36,14 @@
* <TipBox variant="prominent" type="warning"> * <TipBox variant="prominent" type="warning">
* This is an important security warning * This is an important security warning
* </TipBox> * </TipBox>
*
* <TipBox variant="protip">
* This is a valuable pro tip
* </TipBox>
*/ */
type TipType = 'info' | 'warning' | 'success'; type TipType = 'info' | 'warning' | 'success';
type TipVariant = 'compact' | 'prominent'; type TipVariant = 'compact' | 'prominent' | 'protip';
interface TipBoxProps { interface TipBoxProps {
children: React.ReactNode; children: React.ReactNode;
@ -39,10 +51,10 @@ interface TipBoxProps {
type?: TipType; type?: TipType;
} }
const icons: Record<TipType, string> = { const icons: Record<TipType, React.ReactNode> = {
info: '💡', info: <Lightbulb className="w-5 h-5 text-purple-400" />,
warning: '⚠️', warning: <AlertTriangle className="w-5 h-5 text-amber-400" />,
success: '✓', success: <CheckCircle className="w-5 h-5 text-green-400" />,
}; };
const compactStyles: Record<TipType, string> = { const compactStyles: Record<TipType, string> = {
@ -53,23 +65,49 @@ const compactStyles: Record<TipType, string> = {
const prominentStyles: Record<TipType, string> = { const prominentStyles: Record<TipType, string> = {
info: 'bg-gradient-to-br from-purple-500/5 via-cyan-500/5 to-purple-500/5 border-purple-500/30 text-gray-300 shadow-lg shadow-purple-500/10', info: 'bg-gradient-to-br from-purple-500/5 via-cyan-500/5 to-purple-500/5 border-purple-500/30 text-gray-300 shadow-lg shadow-purple-500/10',
warning: 'bg-gradient-to-br from-amber-500/5 via-orange-500/5 to-amber-500/5 border-amber-500/30 text-gray-300 shadow-lg shadow-amber-500/10', warning:
success: 'bg-gradient-to-br from-green-500/5 via-emerald-500/5 to-green-500/5 border-green-500/30 text-gray-300 shadow-lg shadow-green-500/10', 'bg-gradient-to-br from-amber-500/5 via-orange-500/5 to-amber-500/5 border-amber-500/30 text-gray-300 shadow-lg shadow-amber-500/10',
success:
'bg-gradient-to-br from-green-500/5 via-emerald-500/5 to-green-500/5 border-green-500/30 text-gray-300 shadow-lg shadow-green-500/10',
}; };
export const TipBox = ({ children, variant = 'compact', type = 'info' }: TipBoxProps) => { const protipStyle =
const isCompact = variant === 'compact'; 'bg-gradient-to-r from-amber-500/15 via-yellow-500/10 to-amber-500/15 border-amber-400/40 text-amber-100 shadow-lg shadow-amber-500/20 ring-1 ring-amber-400/20';
const icon = icons[type];
const styleClass = isCompact ? compactStyles[type] : prominentStyles[type];
if (isCompact) { export const TipBox = ({ children, variant = 'compact', type = 'info' }: TipBoxProps) => {
// Protip variant - premium golden style
if (variant === 'protip') {
return (
<div
className={`flex gap-3 p-5 rounded-xl border ${protipStyle}`}
role="note"
aria-label="Pro tip"
>
<span className="flex-shrink-0 mt-0.5">
<Sparkles className="w-5 h-5 text-amber-300" />
</span>
<div>
<span className="text-xs font-semibold uppercase tracking-wider text-amber-400 block mb-1">
Pro Tip
</span>
<div className="text-sm leading-relaxed">{children}</div>
</div>
</div>
);
}
const icon = icons[type];
const styleClass = variant === 'compact' ? compactStyles[type] : prominentStyles[type];
// Compact style
if (variant === 'compact') {
return ( return (
<div <div
className={`flex gap-3 p-4 rounded-xl border ${styleClass}`} className={`flex gap-3 p-4 rounded-xl border ${styleClass}`}
role="note" role="note"
aria-label={`${type} note`} aria-label={`${type} note`}
> >
<span className="text-lg flex-shrink-0">{icon}</span> <span className="flex-shrink-0 mt-0.5">{icon}</span>
<div className="text-sm leading-relaxed">{children}</div> <div className="text-sm leading-relaxed">{children}</div>
</div> </div>
); );