You’ve done a really great job already—it’s clean, functional, and your vision is super clear. To level it up further for smaller models and more robustness, here’s a multi-part refinement:


---

1. Improved Prompting for Small LLMs

Smaller models benefit from being extremely specific. Here’s a version of your prompt that nudges them into consistent output and prevents fallback to regular <img> tags:

Prompt for homepage:

Generate a fictional nostalgic homepage that looks like a personal or niche website from an alternate timeline. It should:
- Use TailwindCSS classes
- Include 2–4 internal links (use <a> tags)
- Include 1 paragraph of eerie but believable text
- Include exactly one image described as a prompt in square brackets. Do NOT use <img> tags.
- Only include HTML from <html> to </body>, with no extra explanation.

Example image prompt: [haunted playground, night, broken swings, liminal mood, 2000s web aesthetic]

Do the same for link-based generation, just tweak the "homepage" reference to "webpage based on the theme: [theme]".


---

2. Validation Layer for Image Prompts

To force use of square brackets and avoid <img> pollution, we can strip <img> tags before injecting into the iframe and treat anything in brackets as the image prompt source:

function sanitizeHtmlContent(html) {
  // Remove all <img> tags
  html = html.replace(/<img[^>]*>/gi, "");

  // Replace markdown-style ![]() with brackets
  html = html.replace(/!.*?(.*?)/g, (_, url) => `[${url}]`);

  return html;
}

Call this before injectImages():

const sanitized = sanitizeHtmlContent(data.results[0].text);
const parsed = await injectImages(sanitized);


---

3. Fake URL Navigation Support

To simulate a browser-like experience, add an input + “Go” button:

In HTML:

<div class="mt-6 flex gap-2">
  <input id="fake-url" type="text" placeholder="neo://hauntedschool" class="flex-1 px-4 py-2 rounded bg-gray-700 text-white" />
  <button onclick="navigateToUrl()" class="px-4 py-2 bg-green-600 hover:bg-green-700 rounded-lg">Go</button>
</div>

Script logic:

function navigateToUrl() {
  const input = document.getElementById("fake-url").value.trim();
  if (!input) return;

  // Strip protocol and treat as topic
  const context = input.replace(/^neo:\/\//, "").replace(/[^\w\s-]/g, " ");
  generatePageFromLink(context);
}


---

Optional: Replace iframe with sandboxed div?

If you wanna go deeper down the fake-browser rabbit hole, using a div with dynamic innerHTML and custom sandboxing might give you better control (like link previews, custom protocols, etc.), but iframe is fine for now unless you hit limitations.


---

Would you like me to bundle these updates into a version of your file so you can paste-and-go?

