DEV Community

Cover image for I built a Chrome extension to deploy AI-generated HTML in one click
Julie Do
Julie Do

Posted on

I built a Chrome extension to deploy AI-generated HTML in one click

The problem I kept running into

Every time I used Claude or ChatGPT to build a quick landing page or a
microsite prototype, I hit the same wall at the end.

The HTML looked great. But getting it live meant:

  1. Copy the code out of the chat window
  2. Create a new project on Netlify (or push to a GitHub repo)
  3. Wait for the deploy pipeline
  4. Share the link

For a developer, that's maybe 5 minutes of boring overhead. But for a marketer or no-code builder? It might as well be a locked door.

And even for me — when I'm doing it 10+ times a week across small
client projects — those 5-minute tasks add up fast.


What I built

HTML Deployer is a Chrome extension that sits inside your AI chat session (ChatGPT, Claude, Gemini) and adds a Deploy button directly next to every HTML code block.

Click it → preview the page on desktop, tablet and mobile → choose
where to publish → done.

No copy-paste. No tab switching. No terminal.


The four deploy targets

I wanted to avoid locking users into a single platform. So the
extension currently supports:

Target Best for
Netlify Free CDN, HTTPS, custom domain — easiest for most people
Vercel Fast preview URLs, zero config
GitHub Pages Version-controlled static hosting, free forever
FTP / cPanel Your own shared hosting — most agencies already have this
Self-hosted agent A tiny PHP file on your server, no FTP credentials stored in the extension
ZIP export Download and upload manually — maximum flexibility


The self-hosted option was a deliberate design choice. A lot of
freelancers and small agencies have existing hosting accounts they're paying for. There was no reason to force them onto Netlify just because it's the path of least resistance.


How it actually works (technical overview)

When the extension loads on a supported AI page, it uses a
MutationObserver to watch for new <code> blocks being rendered in the DOM. When it detects a block that looks like an HTML document (it checks for <!DOCTYPE, <html>, or <body> tags), it injects asmall Deploy button into the parent element.

// Simplified detection logic
const observer = new MutationObserver(() => {
  document.querySelectorAll('pre code').forEach(block => {
    if (isHTMLDocument(block.textContent) && !block.dataset.hdInjected) {
      injectDeployButton(block);
      block.dataset.hdInjected = 'true';
    }
  });
});

observer.observe(document.body, { childList: true, subtree: true });
Enter fullscreen mode Exit fullscreen mode

For the preview, the extension renders the HTML in a sandboxed iframeinside a side panel. It uses CSS transforms to simulate three viewport sizes without making any network requests — everything stays local.


For Netlify and GitHub deploys, the extension uses their respective
REST APIs. Credentials are stored in Chrome's storage.local (not
synced across devices, not sent to our servers).

For FTP deploys, the extension talks to a small backend proxy (because browsers can't open raw TCP connections). The FTP credentials are encrypted in transit and not logged or stored on our side.


The self-host option explained

Some users — particularly agencies with client hosting accounts — don't want to enter FTP credentials into a browser extension at all. That's a completely reasonable security concern.

The self-hosted mode works like this:

  1. You download a single agent.php file (~30 lines)
  2. You upload it to your own server
  3. You point the extension at your server URL + a secret token you set

The extension sends the HTML payload to your own server, which writes the file to disk. Your FTP credentials never leave your server. The extension only knows the public URL of the agent.

<?php
// Simplified agent.php
$token = 'your-secret-token-here';
if ($_SERVER['REQUEST_METHOD'] !== 'POST') exit;
if ($_POST['token'] !== $token) http_response_code(403) and exit;

$filename = basename($_POST['filename'] ?? 'index.html');
$html = $_POST['html'] ?? '';
file_put_contents(__DIR__ . '/' . $filename, $html);

echo json_encode(['url' => 'https://' . $_SERVER['HTTP_HOST'] . '/' . $filename]);
Enter fullscreen mode Exit fullscreen mode

Not fancy, but effective.


What the workflow actually looks like

Here's a typical session for a freelancer building a landing page for a client:

  1. Open Claude
  2. Ask it to build a landing page with a specific offer and CTA
  3. HTML Deployer auto-detects the code block
  4. Click the Deploy button in the sidebar
  5. Preview looks good on mobile — approve
  6. Select Netlify, click Deploy
  7. Get a live URL + QR code in about 8 seconds
  8. Send the URL to the client for feedback

The whole thing from "AI generates the code" to "client has a link" is under 2 minutes. Previously, that same flow was 10–15 minutes of
switching between tabs, copying code, creating Netlify projects, etc.


What I learned building this

MutationObserver is your friend — but also your enemy.
AI chat interfaces re-render constantly. ChatGPT in particular
re-renders code blocks multiple times as streaming completes. I had to add debouncing and a dataset flag to avoid injecting the button multiple times into the same block.

Browser storage is trickier than it looks.
chrome.storage.local has a 5MB limit per item. For an extension that stores deploy history, that fills up faster than you'd expect if someone is deploying large HTML files with embedded base64 images. I had to add a cleanup routine that prunes old history entries.

Users are more security-conscious than I expected.
The most common first question was: "Does this store my FTP
credentials?"
— not "How does the preview work?". That pushed me to build the self-host option earlier than planned, and to make the
security model explicit in the onboarding flow.


Try it

HTML Deployer is free to install on Chrome Web Store:
Install HTML Deployer

If you have a use case that doesn't fit the current deploy targets, or you find a bug, feel free to drop a comment below or reach out.

Would genuinely love to hear how other builders are handling the
"AI output → live page" gap in their workflows.

Top comments (2)

Collapse
 
merbayerp profile image
Mustafa ERBAY

What I like most about this isn’t the extension itself—it’s the problem you’re solving.

A lot of attention is focused on generating code with AI, but much less attention is paid to the friction that comes after generation. Copying code, creating projects, configuring hosting, and sharing previews may only take a few minutes each time, but they completely interrupt the creative flow. It feels like we’re moving toward a world where the gap between “I have an idea” and “I have a live URL” keeps shrinking. Also, the self-hosted agent option was a smart addition. In my experience, security concerns often matter more to users than the underlying technology itself.

Nice example of removing workflow friction rather than adding more features.

Collapse
 
juliedechili profile image
Julie Do

Thank you, hope you will try and enjoy it!