oxc-project/oxc · error · OxcDiagnostic
React 19 disallows `javascript:` URLs as a security precauti
Error message
React 19 disallows `javascript:` URLs as a security precaution.
What it means
Diagnostic from react/jsx-no-script-url (category: suspicious). It flags javascript: URLs in link attributes — <a href="javascript:void(0)"> — because such URLs are an XSS vector when unsanitized data reaches them. The matcher (JS_SCRIPT_REGEX) tolerates mixed case and embedded \r/\n/\t between the letters, so obfuscated variants like 'jav\tascript:...' are still caught. React 16.9 warned about these URLs and React 19 disallows them entirely, hence the message; the help suggests using event handlers instead.
Source
Thrown at crates/oxc_linter/src/rules/react/jsx_no_script_url.rs:25
},
};
use serde::Deserialize;
use serde_json::Value;
use oxc_ast::{AstKind, ast::JSXAttributeItem};
use oxc_diagnostics::OxcDiagnostic;
use oxc_macros::declare_oxc_lint;
use oxc_span::{GetSpan, Span};
use oxc_str::CompactStr;
use crate::{
AstNode,
context::{ContextHost, LintContext},
rule::{MixedTupleRuleConfig, Rule},
};
fn jsx_no_script_url_diagnostic(span: Span) -> OxcDiagnostic {
OxcDiagnostic::warn("React 19 disallows `javascript:` URLs as a security precaution.")
.with_help("Use event handlers instead if you can.")
.with_label(span)
}
static JS_SCRIPT_REGEX: Lazy<Regex> = lazy_regex!(
r"(j|J)[\r\n\t]*(a|A)[\r\n\t]*(v|V)[\r\n\t]*(a|A)[\r\n\t]*(s|S)[\r\n\t]*(c|C)[\r\n\t]*(r|R)[\r\n\t]*(i|I)[\r\n\t]*(p|P)[\r\n\t]*(t|T)[\r\n\t]*:"
);
#[derive(Debug, Default, Clone)]
pub struct JsxNoScriptUrl(Box<JsxNoScriptUrlConfig>);
#[derive(Debug, Default, Clone)]
pub struct JsxNoScriptUrlConfig {
include_from_settings: bool,
components: FxHashMap<String, Vec<String>>,
}
#[derive(Debug, Default, Clone, Deserialize)]View on GitHub (pinned to e1e7af627c)
Solutions
- Replace the javascript: URL with a real handler: <button onClick={...}> or <a href="#" onClick={e => { e.preventDefault(); fn(); }}>
- If the element only triggers behavior, change the tag to <button type="button"> for correct semantics and a11y
- Register custom link components/props via the rule's components config or linkComponents settings so their URLs are validated too
- Search the codebase for obfuscated variants (mixed case, embedded whitespace) — the regex catches them, so trust the linter over a plain grep
Example fix
// before
<a href="javascript:void(0)" onClick={open}>Open</a>
// after
<button type="button" onClick={open}>Open</button> Defensive patterns
Strategy: validation
Validate before calling
npx oxlint -D react/jsx-no-script-url src/ # also run a security review on link attributes
Prevention
- Never construct href values by string concatenation with user input; use event handlers for behavior
- Before a React 19 upgrade, grep the codebase for javascript: URLs — React 19 refuses them at runtime
- Register custom link components (via the rule's components config or linkComponents settings) so their URL props are checked too
When it happens
Trigger: href="javascript:void(0)" or javascript:-prefixed values on <a>, plus custom link components/props configured via the rule's components option or settings linkComponents (includeFromSettings). React 19 upgrade audits where legacy javascript: hrefs now throw at runtime.
Common situations: Legacy codebases with <a href="javascript:void(0)" onclick=...> patterns pre-React-16; upgrading to React 19 where such URLs are hard-disallowed and crash rendering; link-like custom components (<Link to=...>, <NavLink href=...>) that need to be registered in settings so their URL props are checked.
Related errors
- Using target=`_blank` without rel=`noreferrer` (which implie
- Using target=`_blank` without rel=`noreferrer` or rel=`noope
- all spread attributes are treated as if they contain an unsa
- `button` elements must have an explicit `type` attribute.
- `button` elements must have a valid `type` attribute.
AI-assisted analysis of oxc-project/oxc@e1e7af627c (2026-08-20).
Data as JSON: /api/errors/153d54ad0a2293f0.
Report an issue: GitHub.