🔧 AI Nachrichten IBM Technology: What Is MLflow? Tracing AI Agents & LLM Workflows(17.09.2026 um 13:00 Uhr)
🍏 iOS / Mac OSiPhone 17 review one year later: Still plenty to appreciate(17.09.2026 um 13:37 Uhr)
🤖 Android TippsBYD: Noch mehr Schiffe, um Elektroautos in die Welt zu bringen(17.09.2026 um 13:00 Uhr)
🕵️ SicherheitslückenCVE-2026-8070 | ASUS Armoury Crate up to 6.4.12 permission assignment(17.09.2026 um 13:05 Uhr)
🔧 AI Nachrichten IBM Technology: What Is MLflow? Tracing AI Agents & LLM Workflows(17.09.2026 um 13:00 Uhr)
🍏 iOS / Mac OSiPhone 17 review one year later: Still plenty to appreciate(17.09.2026 um 13:37 Uhr)
🤖 Android TippsBYD: Noch mehr Schiffe, um Elektroautos in die Welt zu bringen(17.09.2026 um 13:00 Uhr)
🕵️ SicherheitslückenCVE-2026-8070 | ASUS Armoury Crate up to 6.4.12 permission assignment(17.09.2026 um 13:05 Uhr)
🔧 Programmierung 🕛 vor 1 Monat 4 Min Lesezeit
0

The one-line bug that broke Open Graph cards on 836 pages

↗ Quelle (dev.to)
🗣️ Stimme:
📑 Inhaltsübersicht

For about a month, every social preview card on a site I build was silently cut off mid-word. Not truncated with an ellipsis — cut inside a word. PDF & image tools, con. The con is converters, sliced in half.



Nobody reported it. Preview cards are the one thing you never see on your own site — they only show up when someone else shares your link on Slack, Discord, or X. So it just sat there, on every page, in every language.



Here's the line that did it:




CODE
// OG card subtitle
<text ...>${esc(String(sub).slice(0, 60))}</text>






slice(0, 60). Take the first 60 characters. Simple, obvious, and wrong — because "60 characters" has no idea where words end. If character 60 lands in the middle of converters, you ship conv.






Why it survived so long



Two reasons, and both are worth internalizing:




  1. The output is invisible to the author. OG cards render off-site. My build succeeded, the page looked fine, the card image generated without error. Everything green. The bug only exists in the one context I never look at.


  2. It was in a shared template. One ogSvg() function renders the card for every tool page. So the bug wasn't on one page — it was on 164 tools × the locales each ships. 836 cards, all the same slice, all cut mid-word.




That second point is the real lesson. A bug in a leaf component hurts one page. A bug in the thing that generates every page hurts all of them at once, and it does it quietly.






The naive fix, and why it isn't enough



The obvious fix is "cut at the last space instead of at character 60":




CODE
const cut = s.slice(0, n);
return cut.slice(0, cut.lastIndexOf(" ")) + "";






This works great for English. It falls apart the moment you have more than one language.



Japanese, Chinese, and Korean don't put spaces between words. 無料オンラインツール is one run of characters with no space to find. lastIndexOf(" ") returns -1, slice(0, -1) chops off the last character, and now your CJK subtitle is missing a character and has a floating ellipsis. You traded a visible English bug for a subtle CJK one.






What actually shipped






CODE
function clip(s, n) {
s = String(s == null ? "" : s).trim();
if (s.length <= n) return s;
const cut = s.slice(0, n);
const sp = cut.lastIndexOf(" ");
// Latin scripts break on the space. CJK has no spaces, so if there's no
// space — or it's too early to be a real word boundary — just hard-cut.
return (sp > n * 0.5 ? cut.slice(0, sp) : cut).replace(/[,·、,\s]+$/, "") + "";
}






The sp > n * 0.5 guard is the whole trick. If the last space sits in a reasonable spot, break there (Latin). If there's no space, or it's suspiciously early — meaning it's probably not a real word boundary — hard-cut the character run (CJK). The trailing replace strips a dangling comma or CJK punctuation so you never get image tools,….



It's not linguistically perfect. It doesn't need to be. It needs to never cut converters into conv and never eat a Japanese character. Those two failures are what people actually see.






The takeaway



If you generate anything from a shared template — OG cards, emails, PDFs, filenames — the failure mode isn't "one broken thing." It's "one broken thing, replicated everywhere, in the one place you never look." Two habits catch it:





  • Look at the artifact, not the build log. The build passing tells you nothing about whether the card reads correctly.


  • slice() is not a text-truncation function. It's a character-count function. The moment human-readable text meets a non-space-delimited language, they stop being the same thing.






I hit this building Toolio, a set of small browser tools that ship in 16 languages — which is exactly why the CJK edge case wasn't optional.

Vollständiger Original-Artikel
Den kompletten Beitrag mit allen Details direkt auf dev.to lesen.
↗ Original-Artikel auf dev.to lesen
Wie bewertest du diesen Beitrag?
1 Klick Feedback
Teilen mit Netzwerk & Team:

Community-Analysen & Experten-Meinungen 0

Verfasse deine eigene Analyse, teile Workarounds oder diskutiere diesen Vorfall im Blog.
Noch keine Community-Analyse verfasst. Markiere einen Textabschnitt oder klicke oben auf Eigene Analyse verfassen“!
Community Pulse: Relevanz-Einschätzung
1 Klick Experten-Votum
🔴 Akute Relevanz 0%
🟡 In Evaluierung 0%
🟢 Keine Auswirkung 0%
Spannende Innovation 0%
Verwandte Story-Cluster & Quellen (Vektor-KI)
Port 8095 Engine
1 Quelle
Mercedes bringt eine günstigere C-Klasse Electric mit Allradantrieb auf den Markt
1 Quelle
Android 17: Diese Samsung-Galaxy-Smartphones bekommen jetzt das Update
1 Quelle
BYD: Noch mehr Schiffe, um Elektroautos in die Welt zu bringen
Ähnliche Beiträge
🔍 Verwandte News

Auch interessante Nachrichten The one-line bug that broke Open Graph cards on 836 pages

Thematisch verwandte Begriffe: oneline, that, broke, Open · 6 Treffer

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...