Build Diaries · 01 ·
From Claude artifact to WordPress post: four bugs you'll hit.
I shipped an interactive Claude artifact as a real WordPress blog post. Four bugs ate ninety minutes. Here is each one — symptom, root cause, fix — so you don't have to find them yourself.
- Bugs found
- 4
- From break to fix
- ~90 min
- Live deploy
- 1
01 · The setup
Why publish a Claude artifact as a real blog post?
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.
02 · Overview
Four bugs you'll meet. Tap each for the deep dive.
In the order they hit my screen. Three are not in any tutorial I could find. The fourth — the grid one — is a classic CSS gotcha that hits in WordPress harder than in any sandbox.
Bug 01
The vanishing article
The hero renders. Scroll down — nothing. Empty space where sections should be. The HTML is in the DOM. Symptom of a reveal-animation system that assumes JavaScript executes — and in WordPress, you can't assume that.
Bug 02
The && killer
Console: SyntaxError: Invalid or unexpected token at a line where you wrote a normal &&. View source: it became &&. That's wptexturize — helpful to HTML, fatal to inline JS.
Bug 03
The grid blowout
A 2-column grid renders 2,703px wide inside a 1,156px viewport. grid-template-columns: 1fr 1fr looks innocent. But 1fr is minmax(auto, 1fr), and auto means min-content.
Bug 04
Theme button reset
Text inside cards doesn't wrap. Hello Elementor's reset.css sets button { white-space: nowrap; }. Your <button class="card"> inherits it. Theme button resets are aggressive.
Bug 01
The vanishing article — your content is there. Just invisible.
You publish. You view. Hero renders fine. Scroll down. White. Open the inspector — the HTML is all there, the CSS is loaded. Pick the path your artifact took and see what happens.
Pick a starting state to see what happens when JavaScript fails for any reason.
opacity: 0 on load JS breaks (any reason) no content ever shown
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 .in class was ever added. The animation that was supposed to reveal content became the thing hiding it.
opacity: 1 by default JS adds .js-on, then hides & animates content always visible
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 — not because JS will fail, but because you'll discover ten reasons it can.
Bug 02
The && killer — wptexturize, in your script tag.
This one cost me the most time. Chrome's console pointed at a line where I wrote a completely normal &&. View-source showed something else. Drag the slider to see where your JavaScript currently sits on the exposure spectrum.
Fully externalized — WordPress never sees your JS source. Safe.
Bug 03
The grid blowout — 1fr is not what you think.
My console said builder-pool.width = 2703px in a 1,156-pixel viewport. So how does 1fr become 1,350 pixels of overflow? Pick what's inside your grid cell to see why.
Pick what's inside the cell to see whether 1fr will hold — or blow up.
1fr works fine
Short text wraps naturally. The min-content size is small. 1fr = minmax(auto, 1fr) stays within the half-cell because auto is tiny.
- Min-content
- Small
- Risk
- None
- Need
minmax(0,…)? - No
Use minmax(0, 1fr)
Long paragraphs inside buttons are the common trigger. The button's min-content is the longest unbreakable word — often surprisingly long. Default 1fr won't shrink below that. minmax(0, 1fr) lets the cell shrink to zero.
- Min-content
- Often huge
- Risk
- High
- Need
minmax(0,…)? - Yes
minmax(0, 1fr) plus overflow-x: auto
Code blocks are the worst offenders — single lines can be hundreds of characters with no wrap point. Use minmax(0, 1fr) on the grid, then overflow-x: auto on <pre> so the long line scrolls inside its cell.
- Min-content
- Unbounded
- Risk
- Extreme
- Need
minmax(0,…)? - Yes — plus overflow:auto
minmax(0, 1fr) plus max-width: 100%
An iframe with a width attribute or an image with intrinsic dimensions can blow out a cell. Cap with max-width: 100% on the media element.
- Min-content
- Asset width
- Risk
- High
- Need
minmax(0,…)? - Yes
minmax(0, 1fr) all the way down
Nested grid/flex layouts cascade min-width: auto down the tree. Apply minmax(0, 1fr) at every grid level and min-width: 0 on every flex container.
- Min-content
- Cascading
- Risk
- High
- Need
minmax(0,…)? - Yes, at every level
Bug 04
The theme button reset — your buttons wear someone else's clothes.
Every major WordPress theme has aggressive <button> resets. Tap each theme to see what it does to your interactive elements.
- Buttons get
white-space: nowrap- Hover override
- bg
#c36, color white - Fix difficulty
- Easy with
!important
Hello Elementor's reset is the most aggressive. Override white-space: normal !important on your interactive button classes — and block the hover background-color override with your own hover rules.
- Buttons get
- padding + bg
- Hover override
- Subtle bg change
- Fix difficulty
- Easy
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.
- Buttons get
- Inherit-friendly
- Hover override
- Minimal
- Fix difficulty
- Trivial
GeneratePress is the most CSS-author-friendly. Your styles mostly win without !important.
- Buttons get
- Block-level reset
- Hover override
- bg + color shift
- Fix difficulty
- Medium
Kadence has block-level resets via its Blocks plugin. Scope your CSS more aggressively — and prefer class selectors over element selectors.
- Buttons get
- WP block defaults
- Hover override
- Covered by global styles
- Fix difficulty
- Easy
Block themes set defaults via global styles JSON. Higher-specificity class selectors win cleanly.
- Buttons get
- Browser default
- Hover override
- Browser default
- Fix difficulty
- None
No theme, no fight. Outside WordPress, your styles just work.
07 · The diff
Before and after, in one click.
All four fixes in one place. Hit the toggle. Watch the broken state become the working one.
BEFORE · BROKEN
opacity: 0on all reveal elements- Inline
<script>in post body grid-template-columns: 1fr 1fr- Theme
button { white-space: nowrap }wins
AFTER · WORKING
- Progressive enhancement —
js-onclass flips visibility <script src>fromwp-content/uploadsgrid-template-columns: minmax(0, 1fr) minmax(0, 1fr)- Class-scoped
white-space: normal !important
08 · The playbook
Seven steps. Repeatable. Tickable.
If you do this twice, write it down. If you do it three times, automate it. Checks are saved locally.
0 / 7 complete
09 · Honest questions
About Claude artifacts on WordPress.
The questions I had to answer while shipping this. Each one is in the FAQ schema for rich results.
What is a Claude artifact?
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.
Why publish a Claude artifact on WordPress instead of using the share link?
Three reasons. First, SEO — the share link doesn't accumulate authority for your domain. Second, control — on your site you can edit, version, A/B test, and instrument it with analytics. Third, durability — share links depend on a third party staying online. Your blog post is yours.
Why did WordPress break the JavaScript in my Claude artifact?
WordPress runs a filter called wptexturize on post content. It encodes ampersands to & for HTML safety. But it runs inside <script> tags too, where && becomes && which is a JavaScript syntax error. Fix: move JS to an external file in wp-content/uploads and reference with <script src>.
Will an interactive HTML post hurt my Core Web Vitals?
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.
Does this approach work with page builders like Elementor and Divi?
Yes. Add min-width: 0 to your top-level wrapper, and prefer minmax(0, 1fr) over plain 1fr for grid columns. That prevents the layout from blowing out when the parent doesn't strictly constrain width.
