Skip to content
svelte-vitals
English
Esc
navigateopen⌘Jpreview
On this page

Rules

Every check svelte-vitals runs, grouped by category.

Every rule svelte-vitals can report, grouped by category. Each rule links to a reference page describing what it checks, why it matters, and how to fix it.

The severities below are the defaults. See Configuration to change a rule’s severity or turn it off.

SEO

Rule Severity Summary
seo/title-presence 🔴 critical Every route should resolve a non-empty <title>.
seo/canonical-url 🟡 warning Every route should include a <link rel=“canonical”> tag.
seo/charset 🟡 warning The page should declare a character encoding with <meta charset>.
seo/description-presence 🟡 warning Every route should include a <meta name=“description”>.
seo/duplicate-description 🟡 warning Each route should have a unique meta description.
seo/duplicate-title 🟡 warning Each route should have a unique <title>.
seo/hreflang 🟡 warning hreflang alternates should use valid codes; x-default is recommended for selector/redirect pages.
seo/html-lang 🟡 warning Your project’s app.html should set the lang attribute on <html>.
seo/image-alt 🟡 warning Every <img> should have an alt attribute.
seo/json-ld-relative-url 🟡 warning URLs in JSON-LD should be absolute.
seo/json-ld-required-props 🟡 warning A recognized @type should include the properties its rich result requires.
seo/json-ld-validity 🟡 warning A page’s JSON-LD must be valid JSON with @context and @type.
seo/og-image 🟡 warning Every route should include a <meta property=“og”> tag.
seo/og-title 🟡 warning Every route should include a <meta property=“og”> tag.
seo/og-url 🟡 warning Every route should include an og with its canonical address.
seo/robots-txt 🟡 warning Your project should provide a robots.txt file.
seo/single-h1 🟡 warning Each page should have exactly one <h1>.
seo/sitemap-xml 🟡 warning Your project should provide a sitemap.xml file.
seo/ssr-disabled 🟡 warning export const ssr = false makes a route’s content invisible to non-JS crawlers and slower to first paint.
seo/viewport 🟡 warning Pages should declare a responsive viewport meta tag.
seo/description-length 🔵 info The meta description should be 70–160 characters.
seo/heading-level-skip 🔵 info Heading levels should not be skipped.
seo/indexability 🔵 info A route should not be accidentally set to noindex.
seo/json-ld 🔵 info Every route should include JSON-LD structured data.
seo/json-ld-date-format 🔵 info Date properties in JSON-LD should be ISO-8601.
seo/json-ld-deprecated-type 🔵 info Some schema types had their Google rich result dropped or restricted.
seo/json-ld-placeholder 🔵 info JSON-LD should not contain unreplaced placeholder text.
seo/og-description 🔵 info Every route should include an og.
seo/sitemap-in-robots 🔵 info robots.txt should point crawlers at your sitemap.
seo/title-length 🔵 info The document title should be 30–60 characters.
seo/twitter-card 🔵 info Pages should declare a twitter for rich sharing on X/Twitter.

Performance

Rule Severity Summary
performance/font-preload-crossorigin 🟡 warning A font preload must set crossorigin so the preloaded file is actually used.
performance/image-dimensions 🟡 warning Every <img> should have explicit width and height attributes.
performance/lcp-image 🟡 warning The first (likely LCP) image should not be lazy-loaded.
performance/load-waterfall 🟡 warning Dependent sequential awaits in a universal load cost a network round trip from the browser per hop.
performance/minify-disabled 🟡 warning A build.minify left in vite.config ships unminified JS/CSS to production.
performance/preload-missing-as 🟡 warning Every <link rel=“preload”> should declare an as attribute.
performance/render-blocking-script 🟡 warning A head <script src> should not block parsing.
performance/heavy-import 🔵 info Avoid importing large, non-tree-shakeable packages.
performance/iframe-loading 🔵 info An offscreen iframe eagerly loads an entire third-party document of scripts, fonts and media, usually costing more than an offscreen image; loading=“lazy” defers it.
performance/image-loading-hint 🔵 info Every <img> should have an explicit loading attribute.
performance/namespace-import 🔵 info Prefer named imports over import * as for tree-shaking.
performance/preconnect 🔵 info Preconnect to third-party origins used by the page.
performance/responsive-image 🔵 info Large images should provide a srcset.
performance/sequential-awaits 🔵 info Awaits that don’t use each other’s results still run one after another; start them together.
performance/state-raw 🔵 info Object/array $state that is only ever reassigned pays for deep reactivity it never uses; $state.raw skips the proxy.

Correctness

Rule Severity Summary
correctness/orphan-effect 🔴 critical An $effect created outside component initialisation throws effect_orphan at runtime.
correctness/orphan-lifecycle 🔴 critical onMount, getContext and friends called outside component initialisation throw lifecycle_outside_component at runtime.
correctness/server-browser-global 🔴 critical window, document, localStorage accessed in module scope or a load/handler crash SSR with a ReferenceError.
correctness/autoplay-muted 🟡 warning Browsers block autoplay with audio, and a blocked autoplay does not error, so a <video autoplay> without muted silently never starts playing for real visitors.
correctness/base-path-navigation 🟡 warning A hardcoded root-relative link resolves against the domain root, not kit.paths.base, so under a base path it lands outside the app and 404s in production.
correctness/checkable-bind-value 🟡 warning bind on a checkbox or radio input binds the DOM value property, which checkbox/radio interaction never changes, so the bound state silently never updates.
correctness/each-index-key 🟡 warning Keying an {#each} block by its index gives items position-based identity, the same bug as no key, only masked.
correctness/each-key 🟡 warning An {#each} block over dynamic data should have a key.
correctness/effect-as-derived 🟡 warning Use $derived instead of an $effect that only assigns state.
correctness/effect-as-onmount 🟡 warning An $effect that reads no reactive value belongs in an event handler, {@attach}, or onMount instead.
correctness/instance-browser-global 🟡 warning A component’s instance script runs on the server during SSR, so window/document reads at its top level crash the render.
correctness/nonreactive-builtin-state 🟡 warning A plain Map, Set, Date, URL, or URLSearchParams in $state is not proxied, so its mutations are invisible to reactivity and the UI silently stops updating.
correctness/prop-mutation 🟡 warning Don’t mutate a prop from $props() unless it is declared $bindable.
correctness/stale-prop-derivation 🟡 warning A value computed from a prop without $derived is evaluated once, so the UI silently stops tracking the parent.
correctness/unmutated-state 🔵 info Use const (or $state.raw) for a $state that is never mutated.

Security

Rule Severity Summary
security/handler-state-write 🔴 critical A load function or action writes to imported module state, shared across all requests on the server.
security/javascript-url 🟡 warning Avoid javascript: URLs in attributes.
security/raw-html 🟡 warning Sanitize the value; {@html} renders unescaped HTML.
security/server-module-state 🟡 warning A module-scope variable in a Kit route or hooks file is reassigned from a function, shared across all requests on the server.
security/shared-state-import 🟡 warning A Kit server/universal file imports a .svelte.ts module holding module-scope $state, one shared instance per server process.

Architecture

Rule Severity Summary
architecture/component-size 🔵 info Very large components should be split up.
architecture/directory-naming 🔵 info A directory should be named in the casing its location declares.
architecture/doc-link-target 🔵 info A documentation link written in a comment must still point at something that exists.
architecture/private-scope-import 🔵 info A unit inside a private directory should not be imported from outside it.
architecture/prop-count 🔵 info Components taking many props are doing too much.
architecture/reserved-directory-names 🔵 info A directory’s subdirectories should only take names declared for that position.
architecture/reserved-name-placement 🔵 info A reserved directory name may appear only in the places declared for it.
architecture/route-component-import 🔵 info A SvelteKit route entry is rendered by the framework, not imported by other components.
architecture/unit-entry-file 🔵 info A directory declared to be a unit should contain a file named after it.

Accessibility

Rule Severity Summary
a11y/accessible-name 🟡 warning A button, link, image button, or iframe needs a way to compute its accessible name.
a11y/aria-hidden-focus 🟡 warning A keyboard-focusable element must not be hidden from assistive technology with aria-hidden=“true”.
a11y/disallowed-aria-props 🟡 warning An aria-* attribute the element’s role does not support is ignored; one the role prohibits, such as a name on a bare div, is a name that is not exposed.
a11y/disallowed-element 🟡 warning Reports every occurrence of the elements a project declares it does not want, and nothing until something is declared.
a11y/duplicate-landmark 🟡 warning A route should have at most one main, banner, and contentinfo landmark.
a11y/id-duplication 🟡 warning Every id in a route should be unique.
a11y/interactive-nesting 🟡 warning An interactive element should not sit inside another interactive element.
a11y/invalid-aria-value 🟡 warning An aria-* attribute’s value should match the type the WAI-ARIA spec defines for it.
a11y/invalid-role 🟡 warning A role attribute should name a concrete WAI-ARIA role, not a typo or an abstract role.
a11y/label-has-control 🟡 warning A label needs a for attribute or a wrapped control to be associated with the field it names.
a11y/no-accesskey 🟡 warning The accesskey attribute assigns a page-level shortcut key whose actual combination varies by browser and OS, is undiscoverable, and conflicts with assistive-technology bindings.
a11y/no-autofocus 🟡 warning autofocus moves focus on page load without the user asking, so screen reader users lose the page context they were building and keyboard users are dropped mid-page.
a11y/no-missing-id-ref 🟡 warning An id reference should point to an id that exists somewhere in the composed route.
a11y/permitted-contents 🟡 warning Every element must be permitted content of its parent, per the HTML content models.
a11y/placeholder-label-option 🟡 warning A required, single-selection select needs an empty first option so users can’t submit it unchanged.
a11y/positive-tabindex 🟡 warning A tabindex above 0 puts the element ahead of every naturally-ordered element on the page, so a single tabindex=“1” reorders keyboard navigation globally.
a11y/required-aria-props 🟡 warning A role that requires state or property attributes needs them present, unless native host semantics already supply them.
a11y/required-element 🟡 warning Every route must contain the elements a project declares, judged on the composed route, so a layout’s <main> counts.
a11y/top-level-landmark 🟡 warning A banner, main, complementary, or contentinfo landmark should not be nested inside another landmark.
a11y/unknown-aria-attribute 🟡 warning An aria-* attribute should name a real WAI-ARIA attribute, not a typo.
a11y/abbr-title 🔵 info An <abbr> without a title gives readers no expansion. Visual users get no tooltip and assistive technology has nothing to expand.
a11y/deprecated-aria 🔵 info A role or aria-* attribute ARIA 1.3 has deprecated, globally or on the role it sits on, still works today and is no longer defined there.
a11y/deprecated-attr 🔵 info An attribute the HTML spec data marks deprecated on this element has its behavior defined by legacy compatibility, not by the standard.
a11y/deprecated-element 🔵 info An element in the HTML standard’s obsolete-features list is non-conforming and has a conforming replacement.
a11y/doctype 🔵 info src/app.html should open with <!doctype html>.
a11y/no-duplicate-dt 🔵 info Within a single dl element there should not be more than one dt element for each name; a duplicated term usually means two descriptions were meant to share one dt.
a11y/pattern-title 🔵 info When an input has a pattern, the spec says authors should include a title describing the expected format; without it a failed submit tells the user only that the value is wrong.
a11y/require-datetime 🔵 info A time element’s text should be machine-readable, or a datetime attribute should supply the machine-readable value.
a11y/unverified-id-ref 🔵 info Opt-in: flags id references that cannot be verified on routes whose composition is not fully resolved.
a11y/use-list 🔵 info A bullet character typed into plain text should be a real list element instead.