Skip to content

normalizeResourceLocator mangles absolute URLs by appending a trailing slash, breaking <a href> links #47

Description

@Rogultum

Describe the bug:

useNormalizedUrl → normalizeResourceLocator (packages/render/src/helpers/normalizeResourceLocator.ts) parses every anchor href with React Native's URL polyfill:

if (!baseUrl) {
return new URL(url).href;
}
React Native's URL implementation (Libraries/Blob/URL.js) unconditionally appends a trailing / to an absolute URL's path when the path doesn't already end in /, ?, or #. So a real, working URL like:

https://example.com/files/report.pdf
comes out of normalizeResourceLocator as:

https://example.com/files/report.pdf/
This is passed as the href argument to RenderersProps['a'].onPress (and used internally when the library itself opens the link), so by default every absolute link with a path segment is corrupted before it's opened — e.g. a PDF link 404s, a shortened link (bit.ly/...) fails to resolve, etc. Origin-only URLs (https://example.com) are unaffected.

To Reproduce

import normalizeResourceLocator from '@native-html/render/src/helpers/normalizeResourceLocator';

console.log(normalizeResourceLocator('https://example.com/files/report.pdf'));
// → "https://example.com/files/report.pdf/" (should be unchanged)

console.log(normalizeResourceLocator('https://bit.ly/abc123'));
// → "https://bit.ly/abc123/" (breaks the redirect)
Or in a full app: render link with RenderHtml and open it — the default anchor handler opens the /-suffixed URL.

Expected behavior

An already-absolute URL should be returned unchanged (or at least without an added trailing slash) when it has no baseUrl to resolve against — normalizeResourceLocator's own doc comment says "If the initial URL is absolute, this hook will return this initial URL," which isn't what happens today.

Root cause

This isn't a bug in @native-html/render's own logic — it's an artifact of React Native's URL polyfill (unlike browser/Node URL, RN's implementation normalizes an empty/absent pathname to /) combined with this library relying on new URL(url).href to detect "is this already absolute."

Suggested fix

Guard the "already absolute" case without round-tripping through URL, e.g. test with a regex like /^[a-z][a-z0-9+.-]*:///i (or similar) and return url as-is when it matches, only falling through to new URL(...) for actual relative-URL resolution against baseUrl. Happy to open a PR with this change if that's welcome.

Environment

@native-html/render: 1.0.2 (confirmed still present in 1.0.3 / current master)
React Native: 0.81.5
Platform: iOS + Android

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions