← Back to the feedNote ·

The Missing Spaces Bug That Gives Away AI-Built Astro Sites

3 min read

If you build sites with Claude or another coding agent, and those sites run on Astro, you’ve probably seen this: a space goes missing between two words, usually right after a link. The two words just merge into one, like “read the full guideand the FAQ.”

It happens because Astro drops the line break when a line ends with a link, bold or italic text and the next line starts with plain text, or the other way around. Coding agents wrap long lines all the time, so they walk into this constantly.

It’s a tiny issue. But for anyone who has built sites this way, it’s an obvious giveaway that the site was made with AI. And for visitors who don’t know that, it still signals that nobody was paying attention to the details.

So rather than leaving it, or fixing it by hand every time it shows up, give your coding agent a standing rule.

The rule

Paste this into each project’s CLAUDE.md, or into ~/.claude/CLAUDE.md to cover all your projects at once:

## Rendered whitespace: never glue words to links or inline tags

In JSX/TSX (React, Next.js, Preact, Solid) and in Astro (its HTML compression
is on by default), whitespace that contains a line break is removed when it
sits between text and an element. So this:

```jsx
Read the <a href="/x">full guide</a>
and the FAQ.
```

renders as "full guideand the FAQ." The same happens when a line ends with
text and the next line starts with `<a>`, `<strong>`, `<em>`, `<code>`,
`<span>`, etc.

Rules when writing or editing markup:
- When a line break falls between text and an inline element (in either
  direction), end the line with `{' '}`, or keep the text and the tag on the
  same line.
- After a build, check the rendered HTML (not the source) for glued words.
  Search for `</a>`, `</strong>`, `</em>`, `</code>`, `</span>` directly
  followed by a letter or digit, and for a letter, digit or `,.;:)` directly
  followed by `<a `, `<strong>`, `<em>`, `<code>`, `<span`.
- Static-output projects should have a post-build check that fails the build
  on these patterns, chained into the `build` script (`"build": "<framework
  build> && node scripts/check-html.mjs"`) so a failed check blocks the deploy.
  If a project doesn't have one, add it. Strip `<script>` and `<style>` blocks
  before matching. Let deliberate joins (such as a logo wordmark like
  `Brand<span>Name</span>`) opt out with a `data-glue` attribute.
- After adding the check, test it once by planting a glued word in the build
  output and confirming the check fails.

A few notes

Where it applies. The rule is written for JSX/TSX and Astro, the two common places this happens. Plain HTML, Vue and Svelte keep the space, so the rule does no harm there.

The check script. You don’t need to write it yourself. The rule tells Claude to add one if the project doesn’t have it, and to point it at the right output folder (dist, out or build). The last step matters: having Claude plant a glued word on purpose and watch the build fail proves the check actually works.

Server-rendered apps. Apps like Next.js have no folder of finished HTML to scan. There, the source rule does the work, or the check can run against the next build output or a crawl of the dev server.

The takeaway: Don't fix glued words one by one. Give your coding agent a standing rule, and add a build check that fails when a space goes missing.