{"id":352,"date":"2026-05-24T16:32:20","date_gmt":"2026-05-24T16:32:20","guid":{"rendered":"https:\/\/saveyourclicks.com\/blog\/publishing-claude-artifacts-wordpress-bugs\/"},"modified":"2026-05-24T17:18:02","modified_gmt":"2026-05-24T17:18:02","slug":"publishing-claude-artifacts-wordpress-bugs","status":"publish","type":"post","link":"https:\/\/saveyourclicks.com\/blog\/en\/build-diaries\/publishing-claude-artifacts-wordpress-bugs\/","title":{"rendered":"Publishing Claude Artifacts on WordPress: 4 Bugs You&#8217;ll Hit"},"content":{"rendered":"\n<link rel=\"preconnect\" href=\"https:\/\/fonts.googleapis.com\">\n<link rel=\"preconnect\" href=\"https:\/\/fonts.gstatic.com\" crossorigin>\n<link rel=\"preload\" as=\"style\" href=\"https:\/\/fonts.googleapis.com\/css2?family=Inter:wght@400;500;600;700;800&#038;display=swap\">\n<link rel=\"stylesheet\" href=\"https:\/\/fonts.googleapis.com\/css2?family=Inter:wght@400;500;600;700;800&#038;display=swap\">\n<link rel=\"stylesheet\" href=\"\/blog\/wp-content\/uploads\/build-diaries\/article-01.css?v=2\">\n\n<script type=\"application\/ld+json\">\n{\n  \"@context\": \"https:\/\/schema.org\",\n  \"@type\": \"FAQPage\",\n  \"mainEntity\": [\n    { \"@type\":\"Question\",\"name\":\"What is a Claude artifact?\",\"acceptedAnswer\":{\"@type\":\"Answer\",\"text\":\"A Claude artifact is a self-contained piece of code or content (HTML, React, SVG, document) that Claude generates as a standalone deliverable. You can share it as a public link, but until you publish it on your own domain it doesn't help your SEO, it isn't yours to customize, and it can disappear if Anthropic changes how artifact sharing works.\"} },\n    { \"@type\":\"Question\",\"name\":\"Why publish a Claude artifact on WordPress instead of using the share link?\",\"acceptedAnswer\":{\"@type\":\"Answer\",\"text\":\"Three reasons. First, SEO \u2014 the share link doesn't accumulate authority for your domain. Second, control \u2014 on your site you can edit, version, A\/B test, and instrument it with analytics. Third, durability \u2014 share links depend on a third party staying online. Your blog post is yours.\"} },\n    { \"@type\":\"Question\",\"name\":\"Why did WordPress break the JavaScript in my Claude artifact?\",\"acceptedAnswer\":{\"@type\":\"Answer\",\"text\":\"WordPress runs a filter called wptexturize on post content. It encodes ampersands to &#038; for HTML safety. But it runs inside <script> tags too, where && becomes &#038;&#038; which is a JavaScript syntax error. Fix: move JS to an external file in wp-content\/uploads.\"} },\n    { \"@type\":\"Question\",\"name\":\"Will an interactive HTML post hurt my Core Web Vitals?\",\"acceptedAnswer\":{\"@type\":\"Answer\",\"text\":\"Only if you're careless. Externalize CSS and JS (they cache). Reduce font weight count. Defer scroll animations until after first paint. With those moves the post can hit LCP under 2 seconds on mobile.\"} },\n    { \"@type\":\"Question\",\"name\":\"Does this approach work with page builders like Elementor and Divi?\",\"acceptedAnswer\":{\"@type\":\"Answer\",\"text\":\"Yes. Add min-width: 0 to your top-level wrapper, and prefer minmax(0, 1fr) over plain 1fr for grid columns \u2014 that prevents the layout from blowing out when the parent doesn't strictly constrain width.\"} }\n  ]\n}\n<\/script>\n<script type=\"application\/ld+json\">\n{\n  \"@context\": \"https:\/\/schema.org\",\n  \"@type\": \"HowTo\",\n  \"name\": \"How to publish a Claude artifact as a WordPress blog post\",\n  \"totalTime\": \"PT2H\",\n  \"step\": [\n    { \"@type\":\"HowToStep\",\"name\":\"Export the artifact as a single HTML file\",\"text\":\"Save the full HTML document Claude generated. Keep CSS in style and JS in script for now.\" },\n    { \"@type\":\"HowToStep\",\"name\":\"Add progressive-enhancement defaults\",\"text\":\"Make all reveal animations visible by default. Only hide them when a js-on class confirms JS has loaded.\" },\n    { \"@type\":\"HowToStep\",\"name\":\"Externalize CSS and JS\",\"text\":\"Upload style.css and script.js to wp-content\/uploads\/. Reference them with link and script src in the post.\" },\n    { \"@type\":\"HowToStep\",\"name\":\"Convert grid columns to minmax(0, 1fr)\",\"text\":\"Replace 1fr with minmax(0, 1fr) everywhere. Stops content from blowing out the grid.\" },\n    { \"@type\":\"HowToStep\",\"name\":\"Override theme button styles\",\"text\":\"If your theme styles buttons with white-space: nowrap, override with white-space: normal !important on your classes.\" },\n    { \"@type\":\"HowToStep\",\"name\":\"Scope CSS to a wrapper\",\"text\":\"Wrap the article body in a div and prefix every CSS selector with that class.\" },\n    { \"@type\":\"HowToStep\",\"name\":\"Publish via Custom HTML block\",\"text\":\"Paste body content into a Gutenberg Custom HTML block. Verify with PageSpeed Insights and Rich Results Test.\" }\n  ]\n}\n<\/script>\n\n<article class=\"bd-article\">\n\n  <!-- ============================ HEADER \/ HERO ============================ -->\n  <header class=\"bd-hero\">\n    <div class=\"bd-container\">\n      <p class=\"bd-eyebrow\"><span class=\"bd-dot\" aria-hidden=\"true\"><\/span>Build Diaries \u00b7 01 \u00b7 <time datetime=\"2026-05-24\">May 24, 2026<\/time><\/p>\n      <p class=\"bd-hero-title\">From <span class=\"bd-grad\">Claude artifact<\/span> to WordPress post: four bugs you'll hit.<\/p>\n      <p class=\"bd-lead\">I shipped an interactive Claude artifact as a real WordPress blog post. Four bugs ate ninety minutes. Here is each one \u2014 symptom, root cause, fix \u2014 so you don't have to find them yourself.<\/p>\n      <dl class=\"bd-stats\">\n        <div><dt>Bugs found<\/dt><dd>4<\/dd><\/div>\n        <div><dt>From break to fix<\/dt><dd>~90 min<\/dd><\/div>\n        <div><dt>Live deploy<\/dt><dd>1<\/dd><\/div>\n      <\/dl>\n    <\/div>\n  <\/header>\n\n  <nav class=\"bd-toc\" aria-label=\"Table of contents\">\n    <div class=\"bd-container\">\n      <ol>\n        <li><a href=\"#setup\">The setup<\/a><\/li>\n        <li><a href=\"#bugs\">Four bugs<\/a><\/li>\n        <li><a href=\"#vanish\">Bug 01: vanishing article<\/a><\/li>\n        <li><a href=\"#amp\">Bug 02: the && killer<\/a><\/li>\n        <li><a href=\"#grid\">Bug 03: grid blowout<\/a><\/li>\n        <li><a href=\"#btn\">Bug 04: theme button reset<\/a><\/li>\n        <li><a href=\"#playbook\">7-step playbook<\/a><\/li>\n        <li><a href=\"#faq\">FAQ<\/a><\/li>\n      <\/ol>\n    <\/div>\n  <\/nav>\n\n  <main class=\"bd-main\">\n\n    <!-- ============================ 01 \u00b7 THE SETUP ============================ -->\n    <section class=\"bd-section\" id=\"setup\">\n      <div class=\"bd-container\">\n        <header class=\"bd-section-header\">\n          <p class=\"bd-section-num\">01 \u00b7 The setup<\/p>\n          <h2>Why publish a Claude artifact as a <em>real blog post<\/em>?<\/h2>\n          <p class=\"bd-section-lead\">A Claude artifact share link is fine for showing one person. But it doesn't earn SEO authority, it isn't yours to edit, and it lives on someone else's infrastructure. The moment you treat the artifact as a real piece of content, those three problems matter.<\/p>\n        <\/header>\n\n        <div class=\"bd-compare\" id=\"compare\">\n          <button class=\"bd-compare-card\" type=\"button\" data-frame=\"link\" aria-pressed=\"false\">\n            <p class=\"bd-tag\">The share link<\/p>\n            <h3>Quick. Disposable.<\/h3>\n            <p>Anthropic hosts it. Nice for a single send. Doesn't accumulate authority for your domain. Can't be edited after the conversation closes. Discoverable only if someone has the link.<\/p>\n          <\/button>\n          <button class=\"bd-compare-card\" type=\"button\" data-frame=\"post\" aria-pressed=\"false\">\n            <p class=\"bd-tag\">The blog post<\/p>\n            <h3>Yours. Indexed. Durable.<\/h3>\n            <p>Lives on your domain. Earns links, ranks for keywords, accumulates topical authority. You can edit, version, A\/B test, and instrument it with analytics.<\/p>\n          <\/button>\n        <\/div>\n        <p class=\"bd-compare-meta\" id=\"compareMeta\">Tap either card. The artifact-as-blog-post path takes more work \u2014 but everything you do compounds on your own domain. <strong>That's the trade.<\/strong><\/p>\n      <\/div>\n    <\/section>\n\n    <!-- ============================ 02 \u00b7 FOUR BUGS ============================ -->\n    <section class=\"bd-section bd-section-alt\" id=\"bugs\">\n      <div class=\"bd-container\">\n        <header class=\"bd-section-header\">\n          <p class=\"bd-section-num\">02 \u00b7 Overview<\/p>\n          <h2>Four bugs you'll meet. <em>Tap each for the deep dive.<\/em><\/h2>\n          <p class=\"bd-section-lead\">In the order they hit my screen. Three are not in any tutorial I could find. The fourth \u2014 the grid one \u2014 is a classic CSS gotcha that hits in WordPress harder than in any sandbox.<\/p>\n        <\/header>\n\n        <div class=\"bd-bug-grid\">\n          <a class=\"bd-bug-card\" href=\"#vanish\">\n            <p class=\"bd-bug-tag\">Bug 01<\/p>\n            <h3>The vanishing article<\/h3>\n            <p>The hero renders. Scroll down \u2014 nothing. Empty space where sections should be. The HTML is in the DOM. Symptom of a reveal-animation system that assumes JavaScript executes \u2014 and in WordPress, you can't assume that.<\/p>\n          <\/a>\n          <a class=\"bd-bug-card\" href=\"#amp\">\n            <p class=\"bd-bug-tag\">Bug 02<\/p>\n            <h3>The &amp;&amp; killer<\/h3>\n            <p>Console: <code>SyntaxError: Invalid or unexpected token<\/code> at a line where you wrote a normal <code>&amp;&amp;<\/code>. View source: it became <code>&amp;#038;&amp;#038;<\/code>. That's wptexturize \u2014 helpful to HTML, fatal to inline JS.<\/p>\n          <\/a>\n          <a class=\"bd-bug-card\" href=\"#grid\">\n            <p class=\"bd-bug-tag\">Bug 03<\/p>\n            <h3>The grid blowout<\/h3>\n            <p>A 2-column grid renders 2,703px wide inside a 1,156px viewport. <code>grid-template-columns: 1fr 1fr<\/code> looks innocent. But <code>1fr<\/code> is <code>minmax(auto, 1fr)<\/code>, and <code>auto<\/code> means min-content.<\/p>\n          <\/a>\n          <a class=\"bd-bug-card\" href=\"#btn\">\n            <p class=\"bd-bug-tag\">Bug 04<\/p>\n            <h3>Theme button reset<\/h3>\n            <p>Text inside cards doesn't wrap. Hello Elementor's <code>reset.css<\/code> sets <code>button { white-space: nowrap; }<\/code>. Your <code>&lt;button class=\"card\"&gt;<\/code> inherits it. Theme button resets are aggressive.<\/p>\n          <\/a>\n        <\/div>\n      <\/div>\n    <\/section>\n\n    <!-- ============================ 03 \u00b7 BUG 01 VANISHING ============================ -->\n    <section class=\"bd-section\" id=\"vanish\">\n      <div class=\"bd-container\">\n        <header class=\"bd-section-header\">\n          <p class=\"bd-section-num\">Bug 01<\/p>\n          <h2>The vanishing article \u2014 your content is there. Just invisible.<\/h2>\n          <p class=\"bd-section-lead\">You publish. You view. Hero renders fine. Scroll down. White. Open the inspector \u2014 the HTML is all there, the CSS is loaded. Pick the path your artifact took and see what happens.<\/p>\n        <\/header>\n\n        <div class=\"bd-paths\" id=\"vanishPaths\">\n          <button class=\"bd-path\" type=\"button\" data-path=\"bad\" aria-pressed=\"false\">\n            <p class=\"bd-path-label\">Default A<\/p>\n            <h3><code>opacity: 0<\/code>, JS reveals on scroll<\/h3>\n          <\/button>\n          <button class=\"bd-path\" type=\"button\" data-path=\"good\" aria-pressed=\"false\">\n            <p class=\"bd-path-label\">Default B<\/p>\n            <h3><code>opacity: 1<\/code> by default, JS animates only if loaded<\/h3>\n          <\/button>\n        <\/div>\n\n        <div class=\"bd-path-result\" id=\"vanishResult\">\n          <p class=\"bd-empty\">Pick a starting state to see what happens when JavaScript fails for any reason.<\/p>\n        <\/div>\n\n        <article class=\"bd-path-card bd-bad\" data-outcome=\"bad\" hidden>\n          <p class=\"bd-path-flow\"><code>opacity: 0<\/code> on load <span aria-hidden=\"true\">\u2192<\/span> JS breaks (any reason) <span aria-hidden=\"true\">\u2192<\/span> <strong>no content ever shown<\/strong><\/p>\n          <p>This is what hit me. The CSS file loaded fine. The JS file had a syntax error elsewhere (Bug 02). Because the JS never reached the IntersectionObserver setup, no <code>.in<\/code> class was ever added. The animation that was supposed to reveal content became the thing hiding it.<\/p>\n        <\/article>\n\n        <article class=\"bd-path-card bd-good\" data-outcome=\"good\" hidden>\n          <p class=\"bd-path-flow\"><code>opacity: 1<\/code> by default <span aria-hidden=\"true\">\u2192<\/span> JS adds <code>.js-on<\/code>, then hides &amp; animates <span aria-hidden=\"true\">\u2192<\/span> <strong>content always visible<\/strong><\/p>\n          <p>Progressive enhancement. The first frame is always readable. If JS loads, you upgrade to the animation. If JS fails, you still have a real article. This is what every interactive blog post needs from day one \u2014 not because JS will fail, but because you'll discover ten reasons it can.<\/p>\n        <\/article>\n      <\/div>\n    <\/section>\n\n    <!-- ============================ 04 \u00b7 BUG 02 && ============================ -->\n    <section class=\"bd-section bd-section-alt\" id=\"amp\">\n      <div class=\"bd-container\">\n        <header class=\"bd-section-header\">\n          <p class=\"bd-section-num\">Bug 02<\/p>\n          <h2>The <code>&amp;&amp;<\/code> killer \u2014 <em>wptexturize, in your script tag.<\/em><\/h2>\n          <p class=\"bd-section-lead\">This one cost me the most time. Chrome's console pointed at a line where I wrote a completely normal <code>&amp;&amp;<\/code>. View-source showed something else. Drag the slider to see where your JavaScript currently sits on the exposure spectrum.<\/p>\n        <\/header>\n\n        <div class=\"bd-ratio\">\n          <div class=\"bd-ratio-display\">\n            <span id=\"ratioVal\">100<\/span>% external <span class=\"bd-muted\">\/ <span id=\"ratioVal2\">0<\/span>% inline<\/span>\n          <\/div>\n          <p class=\"bd-ratio-verdict\" id=\"ratioVerdict\">Fully externalized \u2014 WordPress never sees your JS source. Safe.<\/p>\n          <input type=\"range\" min=\"0\" max=\"100\" value=\"100\" id=\"ratioSlider\" class=\"bd-slider\" aria-label=\"External vs inline JS ratio\">\n          <div class=\"bd-ratio-meta\">\n            <div><dt>wptexturize risk<\/dt><dd id=\"ratioRisk\">None<\/dd><\/div>\n            <div><dt>Browser-cacheable<\/dt><dd id=\"ratioCache\">Yes<\/dd><\/div>\n            <div><dt>Survives edits<\/dt><dd id=\"ratioEdits\">Yes<\/dd><\/div>\n          <\/div>\n        <\/div>\n\n        <aside class=\"bd-callout\">\n          <h3>What wptexturize does inside <code>&lt;script&gt;<\/code><\/h3>\n          <ul>\n            <li><code>&amp;&amp;<\/code> becomes <code>&amp;#038;&amp;#038;<\/code> \u2014 <em>SyntaxError<\/em><\/li>\n            <li>Straight quotes can become curly quotes \u2014 <em>SyntaxError<\/em><\/li>\n            <li>Three dots <code>...<\/code> can become a single ellipsis \u2014 breaks spread syntax<\/li>\n            <li>Double dash <code>--<\/code> can become an em-dash \u2014 breaks decrement<\/li>\n            <li>Even JSON-LD schema is at risk if any value contains <code>&amp;<\/code><\/li>\n          <\/ul>\n        <\/aside>\n      <\/div>\n    <\/section>\n\n    <!-- ============================ 05 \u00b7 BUG 03 GRID ============================ -->\n    <section class=\"bd-section\" id=\"grid\">\n      <div class=\"bd-container\">\n        <header class=\"bd-section-header\">\n          <p class=\"bd-section-num\">Bug 03<\/p>\n          <h2>The grid blowout \u2014 <code>1fr<\/code> is not what you think.<\/h2>\n          <p class=\"bd-section-lead\">My console said <code>builder-pool.width = 2703px<\/code> in a 1,156-pixel viewport. So how does <code>1fr<\/code> become 1,350 pixels of overflow? Pick what's inside your grid cell to see why.<\/p>\n        <\/header>\n\n        <div class=\"bd-tabs\" role=\"tablist\" aria-label=\"Grid cell content\">\n          <button class=\"bd-tab\" type=\"button\" role=\"tab\" data-tab=\"short\">Short text<\/button>\n          <button class=\"bd-tab\" type=\"button\" role=\"tab\" data-tab=\"para\">A paragraph in a button<\/button>\n          <button class=\"bd-tab\" type=\"button\" role=\"tab\" data-tab=\"code\">Code blocks<\/button>\n          <button class=\"bd-tab\" type=\"button\" role=\"tab\" data-tab=\"media\">An iframe or image<\/button>\n          <button class=\"bd-tab\" type=\"button\" role=\"tab\" data-tab=\"nested\">Nested grid\/flex<\/button>\n        <\/div>\n\n        <div class=\"bd-tab-panels\">\n          <article class=\"bd-tab-panel\" data-panel=\"default\" id=\"gridDefault\">\n            <p class=\"bd-empty\">Pick what's inside the cell to see whether <code>1fr<\/code> will hold \u2014 or blow up.<\/p>\n          <\/article>\n          <article class=\"bd-tab-panel\" data-panel=\"short\" hidden>\n            <h3 class=\"bd-verdict-good\"><code>1fr<\/code> works fine<\/h3>\n            <p>Short text wraps naturally. The min-content size is small. <code>1fr = minmax(auto, 1fr)<\/code> stays within the half-cell because <code>auto<\/code> is tiny.<\/p>\n            <dl class=\"bd-spec\">\n              <div><dt>Min-content<\/dt><dd>Small<\/dd><\/div>\n              <div><dt>Risk<\/dt><dd>None<\/dd><\/div>\n              <div><dt>Need <code>minmax(0,\u2026)<\/code>?<\/dt><dd>No<\/dd><\/div>\n            <\/dl>\n          <\/article>\n          <article class=\"bd-tab-panel\" data-panel=\"para\" hidden>\n            <h3 class=\"bd-verdict-warn\">Use <code>minmax(0, 1fr)<\/code><\/h3>\n            <p>Long paragraphs inside buttons are the common trigger. The button's min-content is the longest unbreakable word \u2014 often surprisingly long. Default <code>1fr<\/code> won't shrink below that. <code>minmax(0, 1fr)<\/code> lets the cell shrink to zero.<\/p>\n            <dl class=\"bd-spec\">\n              <div><dt>Min-content<\/dt><dd>Often huge<\/dd><\/div>\n              <div><dt>Risk<\/dt><dd>High<\/dd><\/div>\n              <div><dt>Need <code>minmax(0,\u2026)<\/code>?<\/dt><dd>Yes<\/dd><\/div>\n            <\/dl>\n          <\/article>\n          <article class=\"bd-tab-panel\" data-panel=\"code\" hidden>\n            <h3 class=\"bd-verdict-warn\"><code>minmax(0, 1fr)<\/code> plus <code>overflow-x: auto<\/code><\/h3>\n            <p>Code blocks are the worst offenders \u2014 single lines can be hundreds of characters with no wrap point. Use <code>minmax(0, 1fr)<\/code> on the grid, then <code>overflow-x: auto<\/code> on <code>&lt;pre&gt;<\/code> so the long line scrolls inside its cell.<\/p>\n            <dl class=\"bd-spec\">\n              <div><dt>Min-content<\/dt><dd>Unbounded<\/dd><\/div>\n              <div><dt>Risk<\/dt><dd>Extreme<\/dd><\/div>\n              <div><dt>Need <code>minmax(0,\u2026)<\/code>?<\/dt><dd>Yes \u2014 plus overflow:auto<\/dd><\/div>\n            <\/dl>\n          <\/article>\n          <article class=\"bd-tab-panel\" data-panel=\"media\" hidden>\n            <h3 class=\"bd-verdict-warn\"><code>minmax(0, 1fr)<\/code> plus <code>max-width: 100%<\/code><\/h3>\n            <p>An iframe with a width attribute or an image with intrinsic dimensions can blow out a cell. Cap with <code>max-width: 100%<\/code> on the media element.<\/p>\n            <dl class=\"bd-spec\">\n              <div><dt>Min-content<\/dt><dd>Asset width<\/dd><\/div>\n              <div><dt>Risk<\/dt><dd>High<\/dd><\/div>\n              <div><dt>Need <code>minmax(0,\u2026)<\/code>?<\/dt><dd>Yes<\/dd><\/div>\n            <\/dl>\n          <\/article>\n          <article class=\"bd-tab-panel\" data-panel=\"nested\" hidden>\n            <h3 class=\"bd-verdict-warn\"><code>minmax(0, 1fr)<\/code> all the way down<\/h3>\n            <p>Nested grid\/flex layouts cascade <code>min-width: auto<\/code> down the tree. Apply <code>minmax(0, 1fr)<\/code> at every grid level and <code>min-width: 0<\/code> on every flex container.<\/p>\n            <dl class=\"bd-spec\">\n              <div><dt>Min-content<\/dt><dd>Cascading<\/dd><\/div>\n              <div><dt>Risk<\/dt><dd>High<\/dd><\/div>\n              <div><dt>Need <code>minmax(0,\u2026)<\/code>?<\/dt><dd>Yes, at every level<\/dd><\/div>\n            <\/dl>\n          <\/article>\n        <\/div>\n      <\/div>\n    <\/section>\n\n    <!-- ============================ 06 \u00b7 BUG 04 BUTTON ============================ -->\n    <section class=\"bd-section bd-section-alt\" id=\"btn\">\n      <div class=\"bd-container\">\n        <header class=\"bd-section-header\">\n          <p class=\"bd-section-num\">Bug 04<\/p>\n          <h2>The theme button reset \u2014 <em>your buttons wear someone else's clothes.<\/em><\/h2>\n          <p class=\"bd-section-lead\">Every major WordPress theme has aggressive <code>&lt;button&gt;<\/code> resets. Tap each theme to see what it does to your interactive elements.<\/p>\n        <\/header>\n\n        <div class=\"bd-tabs\" role=\"tablist\" aria-label=\"WordPress theme\">\n          <button class=\"bd-tab bd-tab-active\" type=\"button\" role=\"tab\" data-tab=\"hello\">Hello Elementor<\/button>\n          <button class=\"bd-tab\" type=\"button\" role=\"tab\" data-tab=\"astra\">Astra<\/button>\n          <button class=\"bd-tab\" type=\"button\" role=\"tab\" data-tab=\"generate\">GeneratePress<\/button>\n          <button class=\"bd-tab\" type=\"button\" role=\"tab\" data-tab=\"kadence\">Kadence<\/button>\n          <button class=\"bd-tab\" type=\"button\" role=\"tab\" data-tab=\"block\">Twenty Twenty-Four<\/button>\n          <button class=\"bd-tab\" type=\"button\" role=\"tab\" data-tab=\"none\">None (raw)<\/button>\n        <\/div>\n\n        <div class=\"bd-tab-panels\">\n          <article class=\"bd-tab-panel\" data-panel=\"hello\">\n            <dl class=\"bd-spec\">\n              <div><dt>Buttons get<\/dt><dd class=\"bd-warn\"><code>white-space: nowrap<\/code><\/dd><\/div>\n              <div><dt>Hover override<\/dt><dd class=\"bd-warn\">bg <code>#c36<\/code>, color white<\/dd><\/div>\n              <div><dt>Fix difficulty<\/dt><dd>Easy with <code>!important<\/code><\/dd><\/div>\n            <\/dl>\n            <p>Hello Elementor's reset is the most aggressive. Override <code>white-space: normal !important<\/code> on your interactive button classes \u2014 and block the hover background-color override with your own hover rules.<\/p>\n          <\/article>\n          <article class=\"bd-tab-panel\" data-panel=\"astra\" hidden>\n            <dl class=\"bd-spec\">\n              <div><dt>Buttons get<\/dt><dd>padding + bg<\/dd><\/div>\n              <div><dt>Hover override<\/dt><dd>Subtle bg change<\/dd><\/div>\n              <div><dt>Fix difficulty<\/dt><dd class=\"bd-good\">Easy<\/dd><\/div>\n            <\/dl>\n            <p>Astra is gentler. You'll still want to override padding if you've set your own card padding, but the cascade mostly resolves in your favor.<\/p>\n          <\/article>\n          <article class=\"bd-tab-panel\" data-panel=\"generate\" hidden>\n            <dl class=\"bd-spec\">\n              <div><dt>Buttons get<\/dt><dd class=\"bd-good\">Inherit-friendly<\/dd><\/div>\n              <div><dt>Hover override<\/dt><dd class=\"bd-good\">Minimal<\/dd><\/div>\n              <div><dt>Fix difficulty<\/dt><dd class=\"bd-good\">Trivial<\/dd><\/div>\n            <\/dl>\n            <p>GeneratePress is the most CSS-author-friendly. Your styles mostly win without <code>!important<\/code>.<\/p>\n          <\/article>\n          <article class=\"bd-tab-panel\" data-panel=\"kadence\" hidden>\n            <dl class=\"bd-spec\">\n              <div><dt>Buttons get<\/dt><dd class=\"bd-warn\">Block-level reset<\/dd><\/div>\n              <div><dt>Hover override<\/dt><dd class=\"bd-warn\">bg + color shift<\/dd><\/div>\n              <div><dt>Fix difficulty<\/dt><dd>Medium<\/dd><\/div>\n            <\/dl>\n            <p>Kadence has block-level resets via its Blocks plugin. Scope your CSS more aggressively \u2014 and prefer class selectors over element selectors.<\/p>\n          <\/article>\n          <article class=\"bd-tab-panel\" data-panel=\"block\" hidden>\n            <dl class=\"bd-spec\">\n              <div><dt>Buttons get<\/dt><dd>WP block defaults<\/dd><\/div>\n              <div><dt>Hover override<\/dt><dd>Covered by global styles<\/dd><\/div>\n              <div><dt>Fix difficulty<\/dt><dd class=\"bd-good\">Easy<\/dd><\/div>\n            <\/dl>\n            <p>Block themes set defaults via global styles JSON. Higher-specificity class selectors win cleanly.<\/p>\n          <\/article>\n          <article class=\"bd-tab-panel\" data-panel=\"none\" hidden>\n            <dl class=\"bd-spec\">\n              <div><dt>Buttons get<\/dt><dd class=\"bd-good\">Browser default<\/dd><\/div>\n              <div><dt>Hover override<\/dt><dd class=\"bd-good\">Browser default<\/dd><\/div>\n              <div><dt>Fix difficulty<\/dt><dd class=\"bd-good\">None<\/dd><\/div>\n            <\/dl>\n            <p>No theme, no fight. Outside WordPress, your styles just work.<\/p>\n          <\/article>\n        <\/div>\n      <\/div>\n    <\/section>\n\n    <!-- ============================ 07 \u00b7 BEFORE\/AFTER ============================ -->\n    <section class=\"bd-section\" id=\"diff\">\n      <div class=\"bd-container\">\n        <header class=\"bd-section-header\">\n          <p class=\"bd-section-num\">07 \u00b7 The diff<\/p>\n          <h2>Before and after, in one click.<\/h2>\n          <p class=\"bd-section-lead\">All four fixes in one place. Hit the toggle. Watch the broken state become the working one.<\/p>\n        <\/header>\n\n        <figure class=\"bd-diff\" id=\"diffFig\">\n          <div class=\"bd-diff-state\" data-state=\"before\">\n            <p class=\"bd-diff-label\">BEFORE \u00b7 BROKEN<\/p>\n            <ul class=\"bd-diff-list\">\n              <li class=\"bd-bad\"><code>opacity: 0<\/code> on all reveal elements<\/li>\n              <li class=\"bd-bad\">Inline <code>&lt;script&gt;<\/code> in post body<\/li>\n              <li class=\"bd-bad\"><code>grid-template-columns: 1fr 1fr<\/code><\/li>\n              <li class=\"bd-bad\">Theme <code>button { white-space: nowrap }<\/code> wins<\/li>\n            <\/ul>\n          <\/div>\n          <div class=\"bd-diff-state\" data-state=\"after\" hidden>\n            <p class=\"bd-diff-label\">AFTER \u00b7 WORKING<\/p>\n            <ul class=\"bd-diff-list\">\n              <li class=\"bd-good\">Progressive enhancement \u2014 <code>js-on<\/code> class flips visibility<\/li>\n              <li class=\"bd-good\"><code>&lt;script src&gt;<\/code> from <code>wp-content\/uploads<\/code><\/li>\n              <li class=\"bd-good\"><code>grid-template-columns: minmax(0, 1fr) minmax(0, 1fr)<\/code><\/li>\n              <li class=\"bd-good\">Class-scoped <code>white-space: normal !important<\/code><\/li>\n            <\/ul>\n          <\/div>\n          <button class=\"bd-btn bd-btn-primary\" id=\"diffBtn\" type=\"button\">Apply all four fixes<\/button>\n          <figcaption>The repeatable shape of publishing AI-built work: each subsequent artifact costs less time as the fixes become reflex.<\/figcaption>\n        <\/figure>\n      <\/div>\n    <\/section>\n\n    <!-- ============================ 08 \u00b7 PLAYBOOK ============================ -->\n    <section class=\"bd-section bd-section-alt\" id=\"playbook\">\n      <div class=\"bd-container\">\n        <header class=\"bd-section-header\">\n          <p class=\"bd-section-num\">08 \u00b7 The playbook<\/p>\n          <h2>Seven steps. <em>Repeatable. Tickable.<\/em><\/h2>\n          <p class=\"bd-section-lead\">If you do this twice, write it down. If you do it three times, automate it. Checks are saved locally.<\/p>\n        <\/header>\n\n        <div class=\"bd-playbook\">\n          <div class=\"bd-playbook-progress\">\n            <div class=\"bd-playbook-bar\"><div class=\"bd-playbook-fill\" id=\"pbFill\"><\/div><\/div>\n            <p class=\"bd-playbook-count\"><span id=\"pbDone\">0<\/span> \/ 7 complete<\/p>\n          <\/div>\n\n          <ol class=\"bd-playbook-list\" id=\"pbList\">\n            <li class=\"bd-step\" data-step=\"1\">\n              <button type=\"button\">\n                <span class=\"bd-check\" aria-hidden=\"true\"><\/span>\n                <span class=\"bd-step-body\">\n                  <span class=\"bd-step-num\">Step 01 \u00b7 Export<\/span>\n                  <strong>Save the artifact as a single HTML file<\/strong>\n                  <span class=\"bd-step-desc\">Full HTML document with head, style, body, script. You'll split it in step 03.<\/span>\n                <\/span>\n                <span class=\"bd-step-time\">~2 min<\/span>\n              <\/button>\n            <\/li>\n            <li class=\"bd-step\" data-step=\"2\">\n              <button type=\"button\">\n                <span class=\"bd-check\" aria-hidden=\"true\"><\/span>\n                <span class=\"bd-step-body\">\n                  <span class=\"bd-step-num\">Step 02 \u00b7 Progressive enhancement<\/span>\n                  <strong>Default-visible content, JS-on hides for animation<\/strong>\n                  <span class=\"bd-step-desc\">Replace <code>.reveal { opacity: 0 }<\/code> with <code>.js-on .reveal { opacity: 0 }<\/code>. First line of script: <code>document.documentElement.classList.add('js-on')<\/code>.<\/span>\n                <\/span>\n                <span class=\"bd-step-time\">~5 min<\/span>\n              <\/button>\n            <\/li>\n            <li class=\"bd-step\" data-step=\"3\">\n              <button type=\"button\">\n                <span class=\"bd-check\" aria-hidden=\"true\"><\/span>\n                <span class=\"bd-step-body\">\n                  <span class=\"bd-step-num\">Step 03 \u00b7 Externalize<\/span>\n                  <strong>CSS and JS as separate files in <code>wp-content\/uploads\/<\/code><\/strong>\n                  <span class=\"bd-step-desc\">wptexturize only runs on post body. External files are untouched. Reference with <code>&lt;link&gt;<\/code> and <code>&lt;script src&gt;<\/code>.<\/span>\n                <\/span>\n                <span class=\"bd-step-time\">~10 min<\/span>\n              <\/button>\n            <\/li>\n            <li class=\"bd-step\" data-step=\"4\">\n              <button type=\"button\">\n                <span class=\"bd-check\" aria-hidden=\"true\"><\/span>\n                <span class=\"bd-step-body\">\n                  <span class=\"bd-step-num\">Step 04 \u00b7 Fix grid columns<\/span>\n                  <strong>Replace every <code>1fr<\/code> with <code>minmax(0, 1fr)<\/code><\/strong>\n                  <span class=\"bd-step-desc\">A simple sed pass on your CSS catches all the cases. This stops grid blowout when content has wide min-content sizes.<\/span>\n                <\/span>\n                <span class=\"bd-step-time\">~3 min<\/span>\n              <\/button>\n            <\/li>\n            <li class=\"bd-step\" data-step=\"5\">\n              <button type=\"button\">\n                <span class=\"bd-check\" aria-hidden=\"true\"><\/span>\n                <span class=\"bd-step-body\">\n                  <span class=\"bd-step-num\">Step 05 \u00b7 Theme button reset<\/span>\n                  <strong>Override <code>white-space<\/code>, <code>width<\/code>, and <code>:hover<\/code><\/strong>\n                  <span class=\"bd-step-desc\">A high-specificity block at the top of CSS that overrides theme button defaults. <code>!important<\/code> on <code>white-space: normal<\/code> and <code>width: 100%<\/code> is the minimum.<\/span>\n                <\/span>\n                <span class=\"bd-step-time\">~5 min<\/span>\n              <\/button>\n            <\/li>\n            <li class=\"bd-step\" data-step=\"6\">\n              <button type=\"button\">\n                <span class=\"bd-check\" aria-hidden=\"true\"><\/span>\n                <span class=\"bd-step-body\">\n                  <span class=\"bd-step-num\">Step 06 \u00b7 Scope the CSS<\/span>\n                  <strong>Prefix every selector with a wrapper class<\/strong>\n                  <span class=\"bd-step-desc\">Wrap the article body in <code>&lt;article class=\"bd-article\"&gt;<\/code>. Run a script that prefixes every CSS rule with <code>.bd-article<\/code>. Now styles only apply inside this one post.<\/span>\n                <\/span>\n                <span class=\"bd-step-time\">~10 min<\/span>\n              <\/button>\n            <\/li>\n            <li class=\"bd-step\" data-step=\"7\">\n              <button type=\"button\">\n                <span class=\"bd-check\" aria-hidden=\"true\"><\/span>\n                <span class=\"bd-step-body\">\n                  <span class=\"bd-step-num\">Step 07 \u00b7 Publish &amp; verify<\/span>\n                  <strong>Custom HTML block + PageSpeed + Rich Results test<\/strong>\n                  <span class=\"bd-step-desc\">Paste body content into Gutenberg Custom HTML. After publish, run PageSpeed (LCP &lt; 2.5s mobile?) and Rich Results Test (FAQPage validates?). Fix anything red.<\/span>\n                <\/span>\n                <span class=\"bd-step-time\">~10 min<\/span>\n              <\/button>\n            <\/li>\n          <\/ol>\n\n          <button class=\"bd-playbook-reset\" id=\"pbReset\" type=\"button\">\u21ba Reset progress<\/button>\n        <\/div>\n      <\/div>\n    <\/section>\n\n    <!-- ============================ 09 \u00b7 FAQ (native <details>) ============================ -->\n    <section class=\"bd-section\" id=\"faq\">\n      <div class=\"bd-container\">\n        <header class=\"bd-section-header\">\n          <p class=\"bd-section-num\">09 \u00b7 Honest questions<\/p>\n          <h2>About <em>Claude artifacts on WordPress.<\/em><\/h2>\n          <p class=\"bd-section-lead\">The questions I had to answer while shipping this. Each one is in the FAQ schema for rich results.<\/p>\n        <\/header>\n\n        <div class=\"bd-faq\">\n          <details>\n            <summary>What is a Claude artifact?<\/summary>\n            <p>A Claude artifact is a self-contained piece of code or content (HTML, React, SVG, document) that Claude generates as a standalone deliverable. You can share it as a public link, but until you publish it on your own domain it doesn't help your SEO, it isn't yours to customize, and it can disappear if Anthropic changes how artifact sharing works.<\/p>\n          <\/details>\n          <details>\n            <summary>Why publish a Claude artifact on WordPress instead of using the share link?<\/summary>\n            <p>Three reasons. First, SEO \u2014 the share link doesn't accumulate authority for your domain. Second, control \u2014 on your site you can edit, version, A\/B test, and instrument it with analytics. Third, durability \u2014 share links depend on a third party staying online. Your blog post is yours.<\/p>\n          <\/details>\n          <details>\n            <summary>Why did WordPress break the JavaScript in my Claude artifact?<\/summary>\n            <p>WordPress runs a filter called <code>wptexturize<\/code> on post content. It encodes ampersands to <code>&amp;#038;<\/code> for HTML safety. But it runs inside <code>&lt;script&gt;<\/code> tags too, where <code>&amp;&amp;<\/code> becomes <code>&amp;#038;&amp;#038;<\/code> which is a JavaScript syntax error. Fix: move JS to an external file in <code>wp-content\/uploads<\/code> and reference with <code>&lt;script src&gt;<\/code>.<\/p>\n          <\/details>\n          <details>\n            <summary>Will an interactive HTML post hurt my Core Web Vitals?<\/summary>\n            <p>Only if you're careless. Externalize CSS and JS (they cache). Reduce font weight count. Defer scroll animations until after first paint. With those moves, the post can hit LCP under 2 seconds on mobile.<\/p>\n          <\/details>\n          <details>\n            <summary>Does this approach work with page builders like Elementor and Divi?<\/summary>\n            <p>Yes. Add <code>min-width: 0<\/code> to your top-level wrapper, and prefer <code>minmax(0, 1fr)<\/code> over plain <code>1fr<\/code> for grid columns. That prevents the layout from blowing out when the parent doesn't strictly constrain width.<\/p>\n          <\/details>\n        <\/div>\n      <\/div>\n    <\/section>\n\n  <\/main>\n\n  <footer class=\"bd-footer\">\n    <div class=\"bd-container\">\n      <p>Build Diaries \u00b7 A series on shipping AI-built work to production \u2014 the bugs, the fixes, and the lessons that didn't make the docs.<\/p>\n      <p class=\"bd-footer-meta\"><time datetime=\"2026-05-24\">May 24, 2026<\/time> \u00b7 by <a href=\"https:\/\/saveyourclicks.com\/\" rel=\"author\">Yusof Ansari<\/a><\/p>\n    <\/div>\n  <\/footer>\n\n<\/article>\n\n<script src=\"\/blog\/wp-content\/uploads\/build-diaries\/article-01.js?v=2\" defer><\/script>\n\n\n","protected":false},"excerpt":{"rendered":"<p>I shipped an interactive Claude artifact as a real WordPress blog post. Here are the four bugs that ate 90 minutes \u2014 wptexturize, CSS grid blowout, theme button reset, the vanishing-content trick \u2014 and the fix for each.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"site-sidebar-layout":"default","site-content-layout":"","ast-site-content-layout":"default","site-content-style":"default","site-sidebar-style":"default","ast-global-header-display":"","ast-banner-title-visibility":"","ast-main-header-display":"","ast-hfb-above-header-display":"","ast-hfb-below-header-display":"","ast-hfb-mobile-header-display":"","site-post-title":"","ast-breadcrumbs-content":"","ast-featured-img":"","footer-sml-layout":"","theme-transparent-header-meta":"","adv-header-id-meta":"","stick-header-meta":"","header-above-stick-meta":"","header-main-stick-meta":"","header-below-stick-meta":"","astra-migrate-meta-layouts":"default","ast-page-background-enabled":"default","ast-page-background-meta":{"desktop":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"ast-content-background-meta":{"desktop":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"footnotes":""},"categories":[103],"tags":[],"class_list":["post-352","post","type-post","status-publish","format-standard","hentry","category-build-diaries"],"lang":"en","translations":{"en":352},"pll_sync_post":[],"_links":{"self":[{"href":"https:\/\/saveyourclicks.com\/blog\/wp-json\/wp\/v2\/posts\/352","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/saveyourclicks.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/saveyourclicks.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/saveyourclicks.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/saveyourclicks.com\/blog\/wp-json\/wp\/v2\/comments?post=352"}],"version-history":[{"count":2,"href":"https:\/\/saveyourclicks.com\/blog\/wp-json\/wp\/v2\/posts\/352\/revisions"}],"predecessor-version":[{"id":355,"href":"https:\/\/saveyourclicks.com\/blog\/wp-json\/wp\/v2\/posts\/352\/revisions\/355"}],"wp:attachment":[{"href":"https:\/\/saveyourclicks.com\/blog\/wp-json\/wp\/v2\/media?parent=352"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/saveyourclicks.com\/blog\/wp-json\/wp\/v2\/categories?post=352"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/saveyourclicks.com\/blog\/wp-json\/wp\/v2\/tags?post=352"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}