To keep anchor links working in a DOCX conversion, preserve both halves of the link: the destination bookmark (or heading) and the hyperlink’s internal target name. Then open the generated file in Word, inspect its bookmarks, click representative links, save, reopen, and—when a link fails—inspect word/document.xml inside the DOCX package. A converter that keeps link text but drops w:bookmarkStart, w:bookmarkEnd, or the target name has removed the navigation contract.
What an anchor link becomes in DOCX
In Markdown or HTML, an anchor normally points to an element ID such as #installation. WordprocessingML represents the same idea with a bookmark range and an internal hyperlink. The range is enclosed by paired w:bookmarkStart and w:bookmarkEnd elements in word/document.xml. The hyperlink stores the bookmark name as its internal destination. Visible link text is only the label; it is not enough to restore navigation.
Word supports two practical destination types:
- Heading targets: Word can list the document’s heading styles when you create a link. This is convenient when the heading text and hierarchy are generated reliably.
- Named bookmarks: an explicit, unique name gives automation a stable identifier even if the visible heading is edited. This is safer for API references, cross-document tooling, and long-lived links.
Word files may also contain a hidden _GoBack bookmark. Its presence is normal and is not evidence that your own anchors survived.
Build a conversion path that keeps targets
1. Define stable destinations in the source
Assign explicit IDs or bookmark names to every destination that matters. Use lowercase letters, digits, and underscores; avoid spaces, punctuation, and duplicate names. Keep a mapping of source ID to intended bookmark name so a later conversion step cannot silently rename targets.
#1 Best Overall
Use heading targets for ordinary sections generated from a controlled outline. Use named bookmarks when a link must remain stable after a heading is rewritten, localized, or restyled. Do not rely on a table of contents alone: its entries are fields or hyperlinks generated from headings, not a substitute for preserving your own bookmark contract.
2. Choose a format-aware converter
The conversion stage must understand DOCX/Open XML rather than flattening the source to plain text and rebuilding paragraphs. Pandoc’s documentation describes DOCX output as appropriate OpenXML; supply a reference DOCX or template when you need controlled styles and predictable heading generation. Keep the conversion command and template under version control so a change in defaults is reviewable.
If you generate DOCX with a library such as python-docx, remember that an internal link’s anchor is the bookmark name. Creating a paragraph that merely looks like a link does not create an internal destination.
3. Carry names and relationships together
For every internal link, verify that the target name in the hyperlink exactly matches a bookmark name in the same document. External URLs use relationships in word/_rels/document.xml.rels; an internal link should retain its anchor target instead of being rewritten as an accidental external relationship. Preserve bookmark start/end IDs as a pair and keep each range in the intended paragraph or table cell.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Create and test links in Word
- Open the source or an intermediate DOCX in Word and apply built-in heading styles to section headings that should be link targets.
- For a named target, select the destination text, choose Insert > Bookmark, enter a unique name, and select Add. Keep the name in your source-to-DOCX mapping.
- Select the link text, choose Insert > Link (or press Ctrl+K), select Place in This Document, then choose a heading or bookmark from the list Word displays.
- Activate the link with Ctrl+Click while editing, or use Word’s link command in reading mode. Confirm that the cursor moves to the intended destination rather than merely selecting text.
- Save, close, and reopen the file. Test again after reopening because a post-processing step or field update can expose malformed targets.
When links are generated rather than authored in Word, reproduce the same result in the converter’s output and use Word only as a validation client. Do not “repair” hundreds of links manually before identifying the conversion defect.
Inspect the DOCX package when a link fails
A DOCX file is a ZIP archive. Make a copy, unzip it, and inspect the XML without editing the original.
Rank #2
unzip converted.docx -d converted_docx
xmllint --format converted_docx/word/document.xml > document.pretty.xml
Inside word/document.xml, a valid bookmark resembles this pattern (the namespace declaration is abbreviated here):
<w:bookmarkStart w:id="42" w:name="installation"/>
<w:r><w:t>Installation</w:t></w:r>
<w:bookmarkEnd w:id="42"/>
The corresponding internal hyperlink should retain the same anchor name:
Do these 3 things before closing this tab:
1Fix the driver behind crashes, sound loss and screen glitches2Clear out junk files and repair common Windows errors3Scan for outdated or missing drivers - takes under a minute<w:hyperlink w:anchor="installation">...</w:hyperlink>
Check all of the following:
- Each
w:bookmarkStarthas a matchingw:bookmarkEndwith the same ID. - Bookmark names are unique and present on the destinations you expect.
- Every internal hyperlink anchor exactly matches a bookmark name, including case.
- Links intended to be internal are not represented only by an external relationship.
- Bookmarks were not moved into deleted text, a generated field, or an unintended table cell during post-processing.
Word’s bookmark dialog is a useful second check: it should list the named destinations you created. XML inspection explains why a missing entry cannot be fixed by changing the visible link label.
Automate validation in continuous integration
The following Python check fails a build when bookmark ranges are unbalanced or an internal hyperlink points to a name that does not exist. It intentionally ignores Word’s hidden implementation bookmarks when reporting missing destinations.
from pathlib import Path
from zipfile import ZipFile
import xml.etree.ElementTree as ET
NS = {'w': 'http://schemas.openxmlformats.org/wordprocessingml/2006/main'}
W = '{%s}' % NS['w']
def check_docx(path):
with ZipFile(path) as z:
root = ET.fromstring(z.read('word/document.xml'))
starts = {}
ends = set()
names = set()
for node in root.iter(W + 'bookmarkStart'):
ident = node.get(W + 'id')
name = node.get(W + 'name')
starts[ident] = name
if name and not name.startswith('_'):
if name in names:
raise ValueError(f'duplicate bookmark: {name}')
names.add(name)
for node in root.iter(W + 'bookmarkEnd'):
ends.add(node.get(W + 'id'))
unclosed = [ident for ident in starts if ident not in ends]
if unclosed:
raise ValueError(f'unclosed bookmark IDs: {unclosed}')
missing = []
for node in root.iter(W + 'hyperlink'):
anchor = node.get(W + 'anchor')
if anchor and not anchor.startswith('_') and anchor not in names:
missing.append(anchor)
if missing:
raise ValueError(f'missing hyperlink targets: {sorted(set(missing))}')
print(f'{path}: {len(names)} named bookmarks and balanced ranges')
check_docx(Path('converted.docx'))
Run this check on every generated artifact, then perform a smaller interactive test in the Word versions and viewers your readers actually use. XML validity does not prove that every viewer implements internal anchors identically.
Compare conversion approaches before standardizing
| Criterion | Questions to answer | Why it matters |
|---|---|---|
| Target fidelity | Are bookmark names, IDs, and hyperlink destinations retained? | Visible link text can survive while navigation is lost. |
| Template and control support | Can you provide a reference DOCX, styles, or custom XML? | Controlled styles make heading targets predictable. |
| Automation | Is the process scriptable and repeatable in CI? | Repeatability prevents hand-edited repairs from returning. |
| Inspection and repair | Can the output package be checked or modified at XML level? | Package access makes failures diagnosable. |
| Cross-version behavior | Does the file open consistently in the Word editions and viewers used by readers? | Viewer support for bookmarks and anchors differs. |
Record converter-specific limitations instead of assuming that two DOCX generators treat headings, tables, tracked changes, and fields the same way. There is no universal published preservation-rate statistic; your validation suite is the meaningful evidence for your source, converter, and delivery environment.
Free tools Windows power users keep installed
One-click scans. No signup required.
Rank #3
Edge cases worth putting in the test suite
- Punctuation in headings: link to a named bookmark rather than depending on a generated slug whose punctuation rules may change.
- Multiple runs: a bookmark may surround text split across several runs after styling or field insertion; verify that its start and end still pair.
- Tables: test links whose destinations and link text are inside table cells. Some converters move or split cell content.
- Tracked changes: accept or reject revisions in a test copy and confirm that bookmark ranges are not left in deleted markup.
- Generated tables of contents: update the field, save, reopen, and test both the generated entry and a body cross-reference.
- Viewer differences: test the actual Word desktop, Word for the web, or third-party viewer used for delivery; a link that works in Word may not work elsewhere.
Troubleshooting anchor-link failures
Link text remains, but clicking does nothing
The destination bookmark was probably dropped or renamed. Search document.xml for the hyperlink’s w:anchor value, then search for a bookmark with the same name. Restore the destination in the source or fix the converter mapping; changing the label cannot recreate it.
Word reports an invalid bookmark
Check for duplicate names, a missing w:bookmarkEnd, or malformed XML introduced by a post-processing script. Compare the failing range with a known-good range and rerun XML validation before opening the file again.
Only some links fail
Compare successful and failed targets for punctuation, duplicate IDs, table placement, tracked changes, and generated fields. A selective failure usually indicates a content pattern that the converter handles differently, not a general Word outage.
Links work in Word but fail in another viewer
Confirm that the viewer supports Word bookmarks and internal hyperlink anchors. If your delivery environment includes multiple viewers, make that compatibility check part of release testing and provide an alternate navigation method such as a table of contents.
Quick wins for a faster PC:
Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →Repair Windows errors before they cause bigger problemsFix Now →Bookmarks disappear after a save or update
Identify the step that rewrites the package: field updates, revision acceptance, templating, or a custom XML transform. Compare the DOCX before and after that step and enforce the automated bookmark check on both artifacts.
Performance, reliability, and maintenance
Bookmark validation is inexpensive compared with rendering or manually reviewing a long document, so run it on every build. Keep a small fixture document containing headings, named bookmarks, tables, tracked edits, and a generated table of contents. Store the expected bookmark names and representative hyperlink anchors as test data.
Rank #4
For reliable releases, archive the converter version, reference template, source-to-bookmark mapping, and validation report with the generated DOCX. Re-run the suite when changing templates, upgrading the converter, adding a new viewer, or changing post-processing code. This catches regressions without claiming that one converter or Word edition is universally superior.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Or skip the browser setup
If you need a visual baseline of the web page before converting its content to DOCX, ScreenshotNeo can capture the source URL with one request. It is a website screenshot API, not a DOCX converter, so use it to compare the rendered source with the document you generate.
See the ScreenshotNeo API documentation for all options. A cURL request:
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
Python:
import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
open("shot.webp", "wb").write(r.content)
Node.js:
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
Before capture, ScreenshotNeo can accept cookie or consent banners and remove more than 60 known consent platforms, newsletter popups, and chat widgets; each cleanup step can be disabled. Bot checks or CAPTCHAs, blank pages, timeouts, failed loads, and cache hits cost nothing, and response headers identify the page verdict and whether it was billed. Its MCP server lets Claude, Cursor, or another MCP client call take_screenshot, get_page_info, and capture_pdf. The free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000 shots. Create a free ScreenshotNeo account to try it.
FAQ
Should every heading receive a named bookmark?
No. Use heading targets for ordinary generated navigation and reserve explicit names for destinations that external systems or long-lived links must address.
Can I fix a broken anchor by renaming the visible heading?
No. The hyperlink’s internal target and the bookmark name must match; visible text is independent of that mapping.
Recommended Free Tools
Is a valid DOCX ZIP enough to prove links work?
No. ZIP and XML validity only show that the package is structurally readable. Click links after reopening in the viewers used by your audience.
Best Value
Why should internal links be checked separately from external URLs?
Internal links use bookmark anchors inside the document, while external URLs use relationships. A conversion can preserve one mechanism and damage the other.
Frequently Asked Questions
Should every heading receive a named bookmark?
No. Use heading targets for ordinary generated navigation and reserve explicit names for destinations that external systems or long-lived links must address.
Can I fix a broken anchor by renaming the visible heading?
No. The hyperlink’s internal target and the bookmark name must match; visible text is independent of that mapping.
The Tool Desk
Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →Outbyte PC Repair FREERepair Windows errors before they cause bigger problemsFix Now →Is a valid DOCX ZIP enough to prove links work?
No. ZIP and XML validity only show that the package is structurally readable. Click links after reopening in the viewers used by your audience.
Why should internal links be checked separately from external URLs?
Internal links use bookmark anchors inside the document, while external URLs use relationships. A conversion can preserve one mechanism and damage the other.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

