RenderShelf

RenderShelf is a personal cloud library for the HTML pages and Markdown documents I create with AI. It turns scattered downloads into a persistent, searchable visual collection where every file can be previewed, managed, and reopened whenever I need it.

Inspiration

AI tools can create useful landing pages, email designs, prototypes, reports, and Markdown documents in seconds. But after generating them, I kept running into a surprisingly basic problem: where do I put these files?

They ended up buried in my Downloads folder or lost inside old conversations. Opening HTML locally was inconvenient, Markdown did not look the way it was meant to, and filenames alone gave me no idea what each artifact contained.

I built RenderShelf because I wanted one permanent place where I could save AI-generated artifacts and see them the way a browser or GitHub would render them.

What it does

RenderShelf lets me:

  • Upload multiple .html, .htm, .md, and .markdown files by picker or drag and drop
  • Store files persistently in a private OpenAI Site, up to 10 MB per file
  • See real miniature HTML previews directly on the dashboard
  • Open complete HTML files in an isolated, browser-like preview
  • Render Markdown in a clean GitHub-style reading view, including tables, task lists, and code
  • Switch between rendered preview and syntax-highlighted source
  • Copy source or a stable private viewer link
  • Search by filename, filter by file type, and sort by date, name, or size
  • Rename, download, and delete stored files
  • Use the responsive interface on desktop or mobile

It is intentionally focused: upload a useful artifact once, and it remains easy to recognize, inspect, and reuse.

Why it matters

AI conversations increasingly produce useful artifacts, but those artifacts often have no durable home after the conversation ends. RenderShelf bridges that gap.

The first files in my own shelf are HTML email designs for Molten Coffee. Instead of repeatedly finding the old chat or opening anonymous files from Downloads, I can now recognize them visually on my dashboard and reopen the full rendered result immediately.

That makes RenderShelf a small but real piece of personal infrastructure—the missing save button for AI-made web pages and documents.

How I built it

RenderShelf is a TypeScript application deployed with ChatGPT Sites. A single edge worker serves the application shell, API, stored content, and isolated preview routes.

Browser dashboard
       |
       v
TypeScript edge worker
   |              |
   v              v
Sites D1       Sites R2
metadata       file bodies
   |
   +--> sandboxed HTML preview
   +--> sanitized Markdown renderer

The storage layer separates metadata from content:

  • Sites D1 stores each file's UUID, name, type, size, object key, and timestamps. Indexed metadata makes the library searchable and sortable.
  • Sites R2 stores the original UTF-8 HTML or Markdown body under a stable object key.
  • The worker exposes focused routes for listing, uploading, reading, renaming, downloading, deleting, and previewing files.
  • The browser uses stable /f/<uuid> viewer routes so each saved artifact can be reopened directly.

For Markdown, I used marked with GitHub-flavored Markdown, DOMPurify sanitization, GitHub-inspired styling, and highlight.js for source and code presentation.

For HTML, each page runs inside an opaque-origin sandboxed iframe. It can render its own scripts, CSS, and interactions without receiving same-origin access to the RenderShelf dashboard or storage.

Safety and reliability

Rendering arbitrary HTML required more than placing a string on a page. RenderShelf includes:

  • Opaque-origin iframe isolation without allow-same-origin
  • A second Content Security Policy sandbox on preview responses
  • Disabled camera, microphone, location, payment, USB, serial, and Bluetooth permissions
  • Blocked form submission, base-URL changes, referrer leakage, and embedding outside RenderShelf
  • DOMPurify sanitization for rendered Markdown
  • Same-origin and custom-header checks for every mutation
  • Strict extensions, UUID validation, filename normalization, UTF-8 validation, and a 10 MB limit
  • Streaming uploads with actual-size verification instead of buffering entire files in worker memory
  • Cleanup and rollback behavior when D1 or R2 operations fail

The project also has strict TypeScript checks, unit tests, and a Miniflare smoke test covering HTML and Markdown uploads, D1/R2 persistence, previews, security headers, renaming, blocked cross-site-style mutations, and deletion.

How I used Codex and GPT-5.6

I used OpenAI Codex with GPT-5.6 as my development partner throughout the build. I began with the personal workflow I wanted—cloud persistence plus faithful HTML and GitHub-style Markdown rendering—and iterated conversationally from product idea to deployed application.

Codex helped me:

  • Translate the idea into a complete product and storage architecture
  • Build the responsive dashboard, uploader, viewer, and file-management flows
  • Connect Sites D1 and R2 and coordinate metadata with stored objects
  • Design the sandbox and Content Security Policy for uploaded HTML
  • Build and sanitize the Markdown rendering pipeline
  • Add validation, rollback behavior, security headers, and automated tests
  • Diagnose an invalid regular-expression escape that initially blocked rendering
  • Replace generic dashboard placeholders with real live HTML previews
  • Test the deployed application against files already stored in production

This was not a one-shot generated mockup. The finished product came from a real build-debug-verify loop with Codex: I used the application, found concrete problems, described the expected behavior, and worked with Codex until the implementation and deployment matched it.

Challenges I ran into

Rendering arbitrary HTML safely

HTML is executable content, not just formatted text. Rendering uploaded pages in the main document could allow their scripts or styles to affect the application. Layered sandboxing preserves a faithful preview while isolating it from RenderShelf.

Building meaningful dashboard previews

A generic HTML icon did not tell me what a saved page contained. Real miniature previews made the dashboard feel like a visual shelf and made files much easier to recognize.

Making Markdown rendering robust

An invalid regular-expression escape initially prevented files from rendering. Fixing it and adding smoke coverage reinforced how important it is to test content renderers against real files, not only ideal examples.

Keeping two storage systems consistent

Uploading a blob is easy. Making it searchable, renameable, downloadable, previewable, and deletable requires D1 metadata and R2 objects to stay consistent even when one operation fails.

Accomplishments I am proud of

  • Built and deployed a complete working product rather than a static prototype
  • Created persistent cloud storage for both HTML and Markdown
  • Delivered real dashboard thumbnails and full interactive HTML previews
  • Built a polished GitHub-style Markdown experience
  • Added source inspection and all the everyday library-management actions
  • Designed security around untrusted HTML rather than treating it as an afterthought
  • Added automated checks that exercise the full D1/R2 workflow
  • Started using RenderShelf for real artifacts from my own work

The result is simple, but it has already made my own workflow easier—which is exactly why it belongs in Apps for Your Life.

What I learned

The best personal tools do not always need a complicated premise. A small recurring frustration can become a valuable product when the entire workflow is handled thoughtfully.

I also learned that:

  • AI-generated artifacts need persistence after the conversation ends
  • HTML should be treated as active content and isolated carefully
  • Visual previews are much more useful than file-type icons
  • Metadata and large file payloads benefit from separate storage systems
  • Reliability includes cleanup and rollback, not only the happy path
  • Conversational iteration with Codex can move quickly from an idea to a tested, deployed product

What's next

Next, I want to add:

  • Folders, tags, favorites, and collections
  • Version history and visual diffs
  • Private share links with expiration controls
  • Multi-file projects containing HTML, CSS, JavaScript, images, and assets
  • A direct Save to RenderShelf workflow for AI-generated artifacts
  • Optional public publishing for pages users choose to share
  • Full-text and semantic search across saved artifacts

My broader vision is for RenderShelf to become the permanent home for useful files created through AI conversations: generate something, save it once, and keep using it.

Built With

  • chatgpt-sites
  • cloudflare-d1
  • cloudflare-r2
  • cloudflare-workers
  • css3
  • dompurify
  • esbuild
  • gpt-5.6
  • highlight.js
  • html5
  • javascript
  • marked
  • miniflare
  • openai-codex
  • typescript
  • vitest
  • wrangler
Share this project:

Updates