Skip to content

Library link primitive: getLinkProps + LinkProps #752

Description

@romain-pm

Part of #749, API sketch in its first comment. The props tier: everything mechanical about turning a target into anchor data.

  • getLinkProps(target, options, context){ anchor, state }. anchor is DOM-spreadable by construction (href, target, rel, title) — the same contract ImageProps has, so <a {...anchor}> is correct in an Island. state (navigable, isCurrent, isAncestor, label) is separate and is never spread.
  • Not-navigable is a first-class result, not an error: falsy target, "" or whitespace-only string (Jahia/jahia.com NavBar.tsx:66 emits href: "" today), a string failing the scheme allow-list, a falsy return from buildNodeUrl, or a missing translation. Never throws — today buildNodeUrl does (urlBuilder.ts:72), and there is no error boundary in the engine or the library.
  • Cache dependency, default on, skipped without a render context. { node } when the target resolves, { uuid } on the raw reference string when it does not — otherwise publishing the target never flushes the cached fallback. Core's nodeLink.jsp:10 registers on the uuid before checking resolution. cacheDependency also accepts an explicit { node } | { path } | { uuid }; { path } is what a JCR-query loop wants (Jahia/jahia.com NavBar.tsx:135).
  • target validated against jmix:link's four values; unknown or unset omits the attribute, never target="". rel="noopener noreferrer" when target resolves to _blank. Both are live/preview guarantees only — EditModeFilter rewrites them in the page builder.
  • isCurrent is identifier equality and is overridable via options; isAncestor is a path-segment test. Not a substring test (luxe NavigationToggler.tsx:32 and industrial both mark /home/news active on /home/newsletter) and not === on node proxies (samples/hydrogen/src/components/NavBar/default.server.tsx:20,27).
  • Scheme allow-list on every string JLink did not build itself, j:url included: http https mailto tel ftp, plus /… and #…. React only substitutes a throwing javascript: URL and matches that scheme alone; data:, blob: and vbscript: are covered by nothing else.
  • parameters and hash compose correctly: query before fragment. appendParameters (urlBuilder.ts:8-14) splits on ? today, so it would produce #main?a=b.
  • label is node.getDisplayableName(), with an explicit override.
  • When language is set, check hasI18N(locale) and the target's j:invalidLanguages (Jahia/jahia.com NavBar.tsx:106-120 does both); no translation means not navigable. Decide whether hasI18N also gets exposed to JS.

Component tier, vocabulary reader and cache-key ergonomics are separate issues. The library is engine-provided at runtime, so this ships with an engine release.

Correction: { uuid } does not work today — RenderHelper.renderTag populates the tag before setting the page context, so AddCacheDependencyTag.setUuid throws a swallowed NullPointerException and nothing is registered (#750). { node }, { path } and { flushOnPathMatchingRegexp } work.

First pass in #751.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    featA new feature

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions