Picture a sales contract leaving your web app with {{client_name}} still sitting in clause one, a week after the template script sailed through QA. Somebody fixed a typo in Word, and Word saved the placeholder as three separate fragments. Expect more of this as editing drifts into browser tabs and more Word files get written by code. The usual culprit is treating a .docx as text or HTML, when it's a zipped bundle of XML parts with no layout until some piece of software calculates one.
A .txt file would never split a placeholder like that. Type a word mid-sentence in one of those and everything after it just slides along by a few bytes. HTML layers tags on top, but a browser still swallows the page as one stream.
A .docx is really a ZIP archive in disguise. Rename it to .zip and you're looking at folders, and even a minimal DOCX package has three of them plus a [Content_Types].xml file that tells software what each part is. Your words end up in word/document.xml, inside w:p, w:r and w:t tags.
Runs are the troublemakers. A run is any stretch of text sharing identical formatting, and Word spawns new ones constantly. A spell-check squiggle can cut a word in two, and so can the rsid attributes Word stamps on text from a different editing session. On screen, nothing changes. Your script, though, searches for {{client_name}} and comes back empty-handed, because the placeholder now spans three runs.
It's a little ironic that find-and-replace, usually the first document feature a team ships, so often turns out to be the first to fall over.
A couple of habits help. Type each template placeholder in one go, with spell check and Track Changes off. Then drop the XML into an XPath evaluation tool and pull every w:t node to confirm each placeholder comes back whole. In code, rebuild a paragraph's text from all of its runs before replacing anything.
Displaying the file raises the same problem in reverse. Plenty of engines turn the DOCX into HTML or a private format before showing it, then translate it back on save, and comment anchors are a common casualty. That conversion step is what separates the options when developers go looking for the best DOCX viewer SDK, since an engine that reads Office Open XML directly has nothing to translate and far less to lose.
Pagination is stranger still, because a .docx doesn't contain pages. Word drops a lastRenderedPageBreak element wherever a page ended during its last layout pass, but that's only a hint, and every other app that opens the file does its own math.
Fonts throw the math off fast. A missing typeface gets swapped for a stand-in with different letter widths, which can shove a signature block onto a lonely page four. Older files bring their own wrinkle, since Compatibility Mode preserves the document's original layout until someone clicks Convert.
Test rendering on a machine that lacks your templates' fonts, and ship those fonts with any server-side renderer. Maybe stop promising that page 12 in the browser is page 12 on paper, too.
Web developers get spoiled by HTML. Browsers are designed to parse HTML whether it is syntactically correct or not, so a forgotten closing div rarely does more than nudge a sidebar. Word's XML has far less patience. Leave one tag unclosed in document.xml and Word typically balks, warning that something's wrong before offering a recovery attempt.
Word checks the package around that XML, too. A PNG missing from [Content_Types].xml, or a relationship ID aimed at a deleted part, can earn you a refusal to open or an empty frame with a red X.
Curious how much is hiding in there? Open word/document.xml from a real contract in an online XML viewer. A two-page NDA can unfold into thousands of lines, most of them invisible to anyone reading.
Styles add a layer most text tools ignore. A paragraph's look builds up from document defaults through a chain of inherited styles, with direct formatting applied last. An editor that can't tell where a bold setting came from may switch off the wrong one.
Lists cause their own damage. That "3." before a clause usually isn't in the text. Word draws it from numbering.xml, through a w:numPr reference tucked into the paragraph. Copy only what's visible and you may get "3. 3." or a list restarting at one, and lawyers notice when clause 7.2 becomes clause 1.
Tables of contents and cross-references are fields, holding an instruction plus whatever result Word calculated last. Rename a few headings without refreshing the fields and the contents page will cheerfully list sections that are long gone. Update all fields before you export a final PDF.
With tracked changes, the stakes become legal. Hit delete with Track Changes on and nothing leaves the file. Word parks the removed words in a w:delText tag inside a w:del element that names the reviewer, so a script that just strips tags hands the clause back as live text.
Leftover revisions embarrassed the UN in October 2005, after its report on the assassination of former Lebanese prime minister Rafik Hariri went online with the tracking still recoverable. GCN's coverage of the episode describes how readers could see names that had been cut from the final text.
Comments are split across the package too, with the reviewer's words in their own part and only range markers in document.xml. A sloppy edit can delete the commented sentence but leave its markers, and the note then latches onto whatever text lands between them.
Anything bound for outside eyes deserves a pass through Word's Document Inspector first, on a copy, because Microsoft says removed data can't always be restored. Accepting or rejecting every revision before the PDF export covers most of the remaining risk.
The package doesn't stop at its own folders. Parts of an Office Open XML file can reference resources at online URLs, a remote template being the classic example, and Word fetches them on opening. Attackers love this, because the nasty part sits on a server and a scanner poking through the attachment can come up clean.
A widely reported case in 2022 showed what remote content inside a Word file can set off. The NVD entry for CVE-2022-30190, better known as Follina, describes remote code execution triggered when an application such as Word calls Microsoft's diagnostic tool through a URL. CISA added it to its list of exploited vulnerabilities that June.
Macros aren't allowed in a .docx at all, so macro-enabled files use .docm. That mattered more once Microsoft said it would block macros in internet-sourced files by default, and Proofpoint's threat researchers found macro-enabled attachments dropped about 66% between October 2021 and June 2022. The crooks simply went looking for other doors.
Upload-and-edit products should scan each .rels file for TargetMode="External" and question anything pointing off-site. [Content_Types].xml is also more trustworthy than a file name, since a .docm renamed to .docx still declares itself macro-enabled.
Round-tripping through HTML is the shortcut a lot of teams try first. The catch is that HTML has no real equivalent of a Word section break with its own margins and headers. As for revisions, the del element records a date and a citation link and nothing more, with nowhere to put a reviewer's name. Every round trip has to invent those details or drop them.
A ticket asking for editable contracts inside the app often gets estimated like a rich textarea. The real cost tends to show up after launch, in front of the paralegals who trusted the feature.
Simple editors still earn their keep. For a README or a scratch note, a plain online text editor is exactly right, because what you see is byte for byte what gets saved. Carrying that expectation into Word files is where people get burned.
The evidence points toward one approach. Edit a DOCX with something that understands what a DOCX actually is, whether that's Word or a native component built into your app. Tools that only skim the surface can get away with it for months, sometimes even longer, and then mangle a contract somebody really cared about.
If your product handles Word files, block out an afternoon this week for an audit. Pull five real documents your customers uploaded, put each through your editing path and open the result in Word. Look hardest at numbered clauses and tracked changes, where the damage usually hides.
And if one of the five is a signed agreement a script edited last, who, exactly, has checked what it says now?