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
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