UID Lookup
A UID (_UID in GEDCOM 5.5.1, UID in GEDCOM 7.0) is a persistent identifier assigned to a record. The UID survives XREF renumbering and tree migrations, making it a stable reference point.
This feature allows navigating directly to a record by its UID. The URL pattern is:
/tree/{tree}/goto-uid/{uid}— scoped to one tree/goto-uid/{uid}— global (searches all trees)
Behavior:
- 0 hits → 404
- 1 visible hit → redirect to the record
- >1 visible hit → selection list (case-variant UIDs or the same UID in multiple records)
UID comparison is case-insensitive (GEDCOM specs do not define UID as case-sensitive). The stored value is verbatim; matching is done case-insensitively so that case-variant UIDs return a selection list rather than a possibly-wrong single redirect.
You can look up UIDs via the quick search input. For shorter UIDs that can be regarded as XREFs, the prefix uid: can be added to the search value.
Standard navigation (goto-id)
goto-id is the standard navigation target for every linkenhancer link — both untyped (wt=@REF@) and typed (wt=<type>@REF@) — and resolves a reference that is either a record XREF or a UID. The URL pattern is:
/tree/{tree}/goto-id/{id}— scoped to one tree (falls back to a global lookup when nothing is found in the tree, with a flash notice)/goto-id/{id}— global (searches all trees)
Behavior (shared IdResolver): the id is tried length-aware and bidirectionally — a long id (≥ 18 chars) as a UID first, a short one as an XREF first — and falls back to the other when the first yields nothing, so a resolution is never lost. 0 hits → 404, 1 visible hit → redirect, >1 → selection list.
sequenceDiagram
autonumber
participant U as 👤 User (Browser)
participant JS as LE JavaScript
participant WT as webtrees Server
participant IR as IdResolver
participant DB as Database
Note over U,JS: Click on an LE link
U->>JS: Click on #@wt=@I234@
JS->>JS: detect href "#@…"
JS->>WT: GET /tree/5/goto-id/I234
WT->>IR: resolve("I234", tree=5)
alt ID short (< 18 chars) → try as XREF first
IR->>DB: SELECT … WHERE xref = 'I234'
DB-->>IR: Match?
else ID long (>= 18 chars) → try as UID first
IR->>DB: SELECT … FROM le_uid_index WHERE uid = '…'
DB-->>IR: Match?
end
alt ✅ 1 match
IR-->>WT: Record
WT-->>U: Redirect to record page
else 0 matches → Fallback
IR->>IR: try the other direction (XREF ⇄ UID)
else >1 matches
WT-->>U: selection list
end
Note over IR,DB: Bidirectional — XREF ⇄ UID<br/>a lookup is never lost
A typed wt=<type>@REF@ link is a legacy form: the type letter is no longer used for routing (all links go through goto-id) and is only documentary — it still drives the diagram link for individuals and the type-mismatch hint in the cross-reference overview. New links should use the untyped wt=@REF@ form.
XREF route (goto-xref)
There is also the route /tree/{tree}/goto-xref/{xref} available, which allows you to navigate to the corresponding record in the tree, regardless of the record type.
Cross-reference overview: UID targets in other trees
In the admin Cross-Reference Overview a link whose UID target is not found in the record’s own tree is normally shown as “target not found”. When the UID feature is enabled, such a target is additionally resolved globally (across the other trees); if matches exist it is rendered as not unique (?) with the match count instead: up to 3 matches are listed as direct cross-tree links, more than 3 collapse into a single goto-id link (title = the UID). This behavior is hard-gated on the UID feature preference and never applies to targets that name an explicit tree.
Index
The UID index is stored in the le_uid_index table (one row per UID tag occurrence, distinguished by tag_path). It is maintained exclusively by build-uid-index.php
(no live scan on request).
- Initial build (first run, or
--rebuild): full scan of all GEDCOM tables, extracting all UID tags viaUidTagCollector. - Incremental runs: only records whose MD5 fingerprint changed (or were added/removed) are re-scanned.
Cron example (every 10 minutes, up to 5000 records per run):
*/10 * * * * cd /path/to/webtrees && php modules_v4/linkenhancer/cli/build-uid-index.php --limit=5000 >> /var/log/linkenhancer-uid-index.log 2>&1
The feature can be toggled on/off in the module admin page (“Activate Support” → [5] UID lookup). The current index status (row count, last build time) is shown there.
While the feature is switched off, index builds are skipped automatically (the cron run exits 0 without doing work). --force builds the index anyway (e.g. to prepare for re-enabling), and --flush works regardless of the switch.
Note: UID tags at any nesting level are indexed (e.g.
0 @I1@ INDI,1 _UID,1 FAMF,2 _UID). The tag path is stored per row so duplicates are distinguishable in the selection list.