Guides

Handling Organization Logos

Turn the Base64 logos posted by CreateOrganization into production-ready assets. This guide covers decoding the payload, pushing the file to your storage provider, and serving performant fallbacks when users skip the upload.

Payload anatomy

The form submits JSON even when an image is dropped. The logoUrl field contains a data: URL with metadata and a Base64 body. Use the structure below to safely split those pieces.

Request body
Tip: keep the original data URL while users are still editing their profile. Only persist to object storage once they confirm the organization.

Uploading to S3 or any object storage

Converting the Base64 string to a Buffer unlocks uploads to S3, Cloudflare R2, Supabase Storage, or any provider that accepts binary data. The snippet below streams the logo into Amazon S3.

/app/api/organizations/route.ts

Replace the public URL with your CDN domain if you are fronting the bucket. Remember to store the uploaded URL on your Organization.logoUrl column so the switcher can render it instantly.

Supporting multipart uploads

If you prefer streaming uploads directly from the client, expose a multipart endpoint. The component automatically falls back to JSON, so support both for maximum compatibility.

pages/api/organizations.ts
Verify: limit accepted MIME types (image/png, image/jpeg, image/svg+xml) and enforce a max size. The component defaults to 5 MB, but you can clamp further on the server.

Generating SVG fallbacks

Some customers will skip the upload. Provide a crisp fallback by generating an SVG emblem on the fly. In many cases you can encode the tenant initials into the gradient background below.

fallback.svg

Store the raw SVG text and inline it inside an <img> tag (data:image/svg+xml;base64,...) so browsers keep the glassmorphism aesthetic even without custom brand assets.