Skip to content

Repository files navigation

EditOverlay

A free, open-source click-to-edit overlay for Next.js landing pages. Toggle Edit Mode, click any element, and change text, colors, sizing, spacing, links, and structure — live. Edits persist to localStorage by default (no backend required).

Optional AI editing: describe changes in natural language ("make the heading bigger and blue") and Claude applies them. Bring your own API key.

Quick start

npx degit vikas8520-coder/edit-overlay my-site
cd my-site
npm install
npm run dev

Open http://localhost:3000, click Edit Mode (bottom-right), and start editing.

Features

Free out of the box (no backend, no API keys):

  • Click-to-edit text, background color, text color, font size, padding
  • Button links (href) that work as real <a> tags in view mode
  • Move elements up/down, add child elements, delete elements
  • Persists to localStorage automatically (debounced)
  • Reset to default at any time

Optional AI editing (bring your own key):

  • Natural language prompts: "rewrite this to be more punchy", "make it green"
  • Powered by Claude Haiku via Anthropic API
  • Only requires ANTHROPIC_API_KEY — no key, no cost

How editing works

Editing is dev-only. The edit button only appears when process.env.NODE_ENV === "development" — i.e., when you run npm run dev on localhost. In production builds, the button is hidden and editing is impossible. No auth, no login, no secrets to manage.

The workflow:

  1. Run npm run dev locally
  2. Click Edit Mode (bottom-right), edit your content
  3. Edits persist to localStorage automatically
  4. When you're happy, copy the saved tree JSON into your code (or commit the localStorage snapshot)
  5. Deploy — production shows the final content, no edit button

This keeps editing simple: it's a developer tool, not a multi-user CMS. You edit locally, commit, deploy. Done.

Stack

  • Next.js (App Router) + TypeScript
  • React 19
  • Tailwind CSS v4
  • No backend required (localStorage default)
  • No auth required (dev-only editing)
  • No UI library

Enable AI editing (optional)

npm install @anthropic-ai/sdk

Create .env.local:

ANTHROPIC_API_KEY=sk-ant-your-key-here

Restart the dev server. The AI edit box now appears in the side panel.

No key? The AI section shows a helpful error when you try to use it. Everything else works fine without it.

Swap localStorage for a database

The persistence layer is a single file: src/lib/persistence.ts. It exports two functions:

export async function loadTree(): Promise<TreeNode | null>
export async function saveTree(tree: TreeNode): Promise<void>

The default implementation uses localStorage. To persist to a database instead, replace the function bodies with fetch calls to your API. Examples for common backends:

Supabase:

export async function loadTree() {
  const { data } = await supabase.from("content").select("tree").eq("key", "landing").single();
  return data?.tree ?? null;
}

export async function saveTree(tree: TreeNode) {
  await supabase.from("content").upsert({ key: "landing", tree });
}

MongoDB (Mongoose):

export async function loadTree() {
  const doc = await ContentModel.findOne({ key: "landing" });
  return doc?.tree ?? null;
}

export async function saveTree(tree: TreeNode) {
  await ContentModel.findOneAndUpdate(
    { key: "landing" }, { tree }, { upsert: true }
  );
}

Any REST API:

export async function loadTree() {
  const res = await fetch("/api/content");
  if (!res.ok) return null;
  const data = await res.json();
  return data.tree ?? null;
}

export async function saveTree(tree: TreeNode) {
  await fetch("/api/content", {
    method: "PUT",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({ tree }),
  });
}

File structure

src/
  app/
    layout.tsx              # root layout
    page.tsx                # client orchestrator: state, persistence, edit mode
    globals.css             # tailwind + edit-mode hover/selected styles
    api/ai-edit/route.ts    # optional AI endpoint (Claude)
  lib/
    tree.ts                 # types, default tree, helpers (find/update/clone)
    treeOps.ts              # structural ops (move/delete/insert/createNode)
    persistence.ts          # swappable persistence adapter (localStorage default)
  components/
    NodeRenderer.tsx        # walks the tree, renders each node by type
    EditOverlay.tsx         # floating View/Edit toggle button
    SidePanel.tsx           # right-side property editor + AI prompt

How it works

The page is not hardcoded JSX — it renders from a JSON node tree (the content model). Each node has a type (heading, paragraph, button, card, etc.), props (text, colors, sizes), and optional children. The NodeRenderer walks this tree and maps each type to a React element.

When you edit, you're modifying the tree in React state. The tree auto-persists (localStorage or your custom backend). On reload, the saved tree is loaded and rendered.

This architecture is what makes every edit persistable and is the same pattern used by visual editors like Lovable, Base44, and Webflow.

Node types

Type Container? Editable props
hero yes bgColor, padding
section yes bgColor, padding
grid yes bgColor, padding
card yes bgColor, padding
footer yes bgColor, padding
heading no text, textColor, fontSize
paragraph no text, textColor, fontSize
button no text, bgColor, textColor, fontSize, padding, href
badge no text, bgColor, textColor, fontSize

License

MIT — free to use, modify, and distribute. See LICENSE.

About

Free, open-source click-to-edit overlay for Next.js landing pages. No backend required. Optional AI editing.

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages