maotoumao/MusicFree · info
dialog.markdownDialog.openExternalLink
Error message
dialog.markdownDialog.openExternalLink
What it means
MarkdownDialog renders untrusted markdown as HTML in a WebView. Its `onShouldStartLoadWithRequest` blocks any http(s) navigation inside the WebView and instead shows a warning toast keyed by `dialog.markdownDialog.openExternalLink`, offering an "打开" (open) action that forwards the URL to the system via openUrl(). This is intentional policy: external links must never load inside the sandboxed WebView.
Source
Thrown at src/components/dialogs/components/markdownDialog.tsx:279
{
title: okText ?? t("dialog.errorLogKnow"),
type: "primary",
onPress() {
hideDialog();
},
},
] as any;
return (
<Dialog onDismiss={hideDialog} >
<Dialog.Title withDivider>{title}</Dialog.Title>
<Dialog.Content style={[{ height: vh(60), maxHeight: vh(60) }, styles.dialogContent]}>
{loading ? <Loading /> : <WebView style={styles.webView} originWhitelist={["*"]} source={{
html: htmlContent,
}}
onShouldStartLoadWithRequest={(event) => {
if (event.url.startsWith("http") || event.url.startsWith("https")) {
Toast.warn(i18n.t("dialog.markdownDialog.openExternalLink"), {
type: "warn",
duration: 3000,
actionText: i18n.t("common.open"),
onActionClick() {
openUrl(event.url);
},
});
}
return false;
}}
/>}
</Dialog.Content>
<Dialog.Actions actions={actions} />
</Dialog>
);
}
View on GitHub (pinned to d118b18b3d)
Solutions
- This is expected behavior — tap the "打开" action on the toast to open the link in the system browser.
- If the toast text appears untranslated, add the `dialog.markdownDialog.openExternalLink` key to the active locale's i18n resource file.
- If no browser opens after tapping "打开", fix the underlying openUrl problem (scheme support / LSApplicationQueriesSchemes).
- Plugin authors should keep links in markdown `[text](https://...)` form so they are intercepted and handled consistently.
Example fix
// before: missing translation key causes raw key to display
// locales/en.json without the key
// after: add the key so users see a readable message
// locales/en.json
"dialog": { "markdownDialog": { "openExternalLink": "External link blocked, open in browser?" } } Defensive patterns
Strategy: fallback
Validate before calling
// inside MarkdownDialog, before rendering html
const safeHtml = htmlContent.replace(
/(https?:\/\/[^\s"'<>]+)/g,
'<a href="$1" onclick="window.ReactNativeWebView && window.ReactNativeWebView.postMessage(JSON.stringify({type:\'link\',url:\'$1\'}));return false;">$1</a>'
); Type guard
function isExternalHttpUrl(url: string): boolean {
return url.startsWith('http://') || url.startsWith('https://');
} Try / catch
onShouldStartLoadWithRequest={(event) => {
if (isExternalHttpUrl(event.url)) {
Toast.warn(i18n.t('dialog.markdownDialog.openExternalLink'), {
type: 'warn',
duration: 3000,
actionText: i18n.t('common.open'),
onActionClick() {
openUrl(event.url).catch(() =>
Toast.warn(i18n.t('dialog.markdownDialog.openExternalLink')));
},
});
return false;
}
return true;
}} Prevention
- Never allow http(s) navigation inside the sandboxed WebView — always intercept and open externally.
- Ensure all locale files define dialog.markdownDialog.openExternalLink so users see readable text.
- Keep the open action resilient: openUrl already swallows failures, but log the URL for diagnosis.
- Escape/untrusted-render markdown before converting to HTML to avoid script injection via href attributes.
When it happens
Trigger: A user taps any http/https link inside markdown-rendered content (song descriptions, plugin docs, changelogs); the WebView's shouldStartLoadWithRequest callback intercepts it and raises the localized warning toast with the open action.
Common situations: Reading a plugin's README inside the markdown dialog and clicking a GitHub link; clicking an image whose src is remote http(s); authors embedding external links in descriptions; users confused why links don't navigate in place.
Related errors
- panel.imageViewer.saveImageFail
- toast.resumeFail
- panel.addToMusicSheet.toast.fail
- 当前歌曲无翻译
- toast.rememberToSave
AI-assisted analysis of maotoumao/MusicFree@d118b18b3d (2026-08-30).
Data as JSON: /api/errors/8fedb844d3b8bd1a.
Report an issue: GitHub.