oxc-project/oxc · warning · OxcDiagnostic
Unexpected `javascript:` url
Error message
Unexpected `javascript:` url
What it means
oxlint's `no-script-url` rule. It flags any string literal that starts with `javascript:` (case-insensitive, via `starts_with_ignore_case`), the URI scheme that executes its body as script. Such URLs are an XSS vector and break CSPs that forbid inline script. The help text says to execute the code directly.
Source
Thrown at crates/oxc_linter/src/rules/eslint/no_script_url.rs:9
use oxc_ast::AstKind;
use oxc_diagnostics::OxcDiagnostic;
use oxc_macros::declare_oxc_lint;
use oxc_span::Span;
use crate::{AstNode, context::LintContext, rule::Rule, utils::starts_with_ignore_case};
fn no_script_url_diagnostic(span: Span) -> OxcDiagnostic {
OxcDiagnostic::warn("Unexpected `javascript:` url")
.with_help("Execute the code directly instead.")
.with_label(span)
}
#[derive(Debug, Default, Clone)]
pub struct NoScriptUrl;
declare_oxc_lint!(
/// ### What it does
///
/// Disallow `javascript:` URLs.
///
/// ### Why is this bad?
///
/// Using `javascript:` URLs is considered by some as a form of `eval`. Code
/// passed in `javascript:` URLs must be parsed and evaluated by the browser
/// in the same way that `eval` is processed. This can lead to security and
/// performance issues.View on GitHub (pinned to e1e7af627c)
Solutions
- Call the function directly: `onclick="doThing()"` in markup or `addEventListener` in script.
- Use `href="#"` with `event.preventDefault()` for placeholder links.
- For `javascript:void(0)` no-ops, use a `<button type="button">` instead.
Example fix
// before const link = `<a href="javascript:void openHelp()">Help</a>`; // after const link = `<button type="button" onclick="openHelp()">Help</button>`;
Defensive patterns
Strategy: validation
Validate before calling
// Detect javascript: URLs in any string, case-insensitively (mirrors starts_with_ignore_case)
function hasScriptUrl(src) {
return /['"`]\s*javascript\s*:/i.test(src);
} Type guard
function isScriptUrl(value) {
return /^\s*javascript\s*:/i.test(String(value));
}
// guard before assigning hrefs:
if (!isScriptUrl(url)) link.setAttribute('href', url); Prevention
- Use `<button type="button">` for action elements instead of `<a href="javascript:void(0)">`.
- Attach behavior with addEventListener and keep hrefs as real URLs or `#`.
- Enforce a CSP without `unsafe-inline` — it makes javascript: URLs fail loudly at runtime, complementing the lint rule.
When it happens
Trigger: `location.href = "javascript:alert('hi')";`, `el.setAttribute('href', 'JavaScript:void(0)')`, `const url = 'javascript:doThing()'` — any StringLiteral whose text begins with the scheme in any casing.
Common situations: Legacy `href="javascript:void(0)"` placeholders in templates; bookmarklet-style navigation; CSP violations surfacing after enabling strict Content-Security-Policy.
Related errors
- eval can be harmful.
- Implied eval. Consider passing a function instead of a strin
- Implied eval. Do not use execScript().
- React 19 disallows `javascript:` URLs as a security precauti
- Empty array binding pattern
AI-assisted analysis of oxc-project/oxc@e1e7af627c (2026-08-20).
Data as JSON: /api/errors/13f73414faecd6a5.
Report an issue: GitHub.