cd /news/ai-tools/your-articles-need-a-copy-for-ai-but… · home › topics › ai-tools › article
[ARTICLE · art-151850] src=markodenic.tech ↗ pub= topic=ai-tools verified=true sentiment=· neutral

Your articles need a “Copy for AI” button

A developer-focused newsletter post proposes adding a "Copy for AI" button to articles so readers can hand AI chats clean Markdown instead of messy select-and-copy output, implemented in roughly 30 lines of JavaScript. The post's toMarkdown function converts headings, paragraphs, lists, links, inline code and fenced code blocks while skipping buttons, navigation, scripts and styles, and it appends the page URL so the model can cite the source. The author argues pasted text beats sharing a URL because many AI tools cannot open links, get blocked by sites, or read cached copies, and Markdown is the format models handle best.

by read4 min views1 publishedOct 17, 2026
Your articles need a “Copy for AI” button
Image: Markodenic (auto-discovered)

Creem.io

Merchant of record payments for SaaS and digital products, handling checkout, subscriptions, taxes, invoices, and global payment operations.

Sponsor this newsletter · reach 9,500+ active developers

Your readers already paste your articles into AI chats. They want a summary, a version of your code for their stack, or an answer to the question your article almost covered. So they select the page, copy, paste.

What the AI gets is a mess: menu links, “Copy” button labels, line numbers glued to the code, and prose and code mashed together with no clear edges. Docs sites have started fixing this with a “Copy for AI” button that hands over a clean Markdown version of the page instead. You can add one in about 30 lines.

The fix #

Walk the article and turn each element into its Markdown equivalent:

function toMarkdown(node) {
  if (node.nodeType === Node.TEXT_NODE) {
    return node.parentNode.closest('p, li, h1, h2, h3') ? node.textContent.replace(/\s+/g, ' ') : '';
  }
  if (node.nodeType !== Node.ELEMENT_NODE || node.matches('button, nav, script, style, [data-no-copy]')) return '';

  const inner = [...node.childNodes].map(toMarkdown).join('');
  const text = inner.trim();

  switch (node.tagName) {
    case 'H1': return `# ${text}\n\n`;
    case 'H2': return `## ${text}\n\n`;
    case 'H3': return `### ${text}\n\n`;
    case 'P': return `${text}\n\n`;
    case 'UL': case 'OL': return `${inner}\n`;
    case 'LI': return `- ${text}\n`;
    case 'STRONG': return `**${text}**`;
    case 'EM': return `_${text}_`;
    case 'A': return `[${text}](${node.href})`;
    case 'CODE': return `\`${node.textContent}\``;
    case 'PRE': {
      const lang = node.querySelector('code')?.className.match(/language-(\w+)/)?.[1] ?? '';
      return `\`\`\`${lang}\n${node.textContent.trim()}\n\`\`\`\n\n`;
    }
    default: return inner;
  }
}

Then copy it on click, with the page URL on top so the AI can point back to the source:

copyButton.addEventListener('click', async () => {
  const markdown = toMarkdown(document.querySelector('article')).trim();
  await navigator.clipboard.writeText(`Source: ${location.href}\n\n${markdown}`);
  copyButton.textContent = 'Copied!';
});

This post has the button. Click “Copy for AI” next to the date at the top, paste it into any AI chat or text editor, and compare it with a plain select-and-copy of the same page.

What the converter handles #

  • Headings, paragraphs, lists: become# , plain text, and- items.
  • Links: keep their full URL, becausenode.href is always absolute. Relative links would be useless outside your site.
  • Code blocks: become fenced blocks, and thelanguage-js class most syntax highlighters add becomes the fence’s language. Inlinecode keeps its backticks.
  • Noise: buttons, navigation, scripts and styles are skipped. Anything else you want left out, like a newsletter signup box in the middle of the article, gets adata-no-copy attribute.
  • Whitespace: text outside paragraphs, list items and headings is dropped. That is almost always the indentation of your HTML, which would otherwise end up as stray spaces.

It is not a full HTML-to-Markdown converter. Tables, images and nested lists are not covered. Add a case when your content needs one: it is one line each.

Why not just give them the URL? #

Some AI tools can open a link. Many cannot, some get blocked by the site, and some read a cached copy from months ago. Pasted text always works, and it is exactly what the reader is looking at right now.

Markdown is also the format models handle best. A heading is one # instead of a wrapper of classes, and code fences mark exactly where code starts and ends, so the model stops mixing your explanation into your code.

Where this comes up #

  • Tutorials and blog posts: “rewrite this for my framework” is the most common thing readers do with them.
  • Documentation: developers paste docs pages into their coding assistant to get help on your API.
  • Changelogs and release notes: “what changed that affects me?”
  • Long policies and guides: support articles, terms, onboarding checklists.

Why this matters #

  • Readers are already doing it: the button only decides whether the AI gets your content clean or garbled.
  • Better answers about your content: clean structure means fewer wrong explanations of your code.
  • It works everywhere: the Clipboard API is supported in every modern browser. It needs HTTPS and a click, which a button already gives you.

If you like where this is going, my issue on letting AI agents use your site with 3 HTML attributes covers the other side: agents using your features, not just reading your content. And if you’d rather offer one button for every app, the native share button is four lines.

Put the button next to your article’s title and paste the result into an AI chat. You will see the difference in the first answer.

Happy coding!

Marko

── more in #ai-tools 4 stories · sorted by recency
── more on @creem.io 3 stories trending now
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain — perfect for shipping the agent you just read about.

$git push zahid main
→ Live at https://your-agent.zahid.host ✓
Get free account → Pricing
from €0/mo · no card required
LIVE [news/your-articles-need-a…] indexed:0 read:4min 2026-10-17 · —