Skip to main content
interlace
Plugin: conventionsRules

no-raw-cross-property-href

Forbid hand-written cross-property hrefs; use buildUtmHref() from lib/utm.ts

Forbid hand-written hrefs between our own properties — route them through buildUtmHref()

Rule Details

Links between our own properties (docs → blog, blog → storybook, …) must carry the UTM taxonomy so cross-property journeys are attributable. A hand-written <a href="https://eslint.interlace.tools"> ships without attribution and that click becomes $direct noise on the destination.

buildUtmHref() is the one blessed constructor: it appends the canonical utm_source / utm_medium pair for the property the code lives in. The rule flags raw href literals pointing at any sibling property.

External links (GitHub, npm, MDN, …), same-site paths and anchors are ignored — attribution is only our own cross-property problem.

Examples

❌ Incorrect

<a href="https://eslint.interlace.tools/docs">docs</a>

✅ Correct

<a href={buildUtmHref('https://eslint.interlace.tools/docs')}>docs</a>

// Not cross-property — all fine as raw literals:
<a href="/docs">docs</a>
<a href="#section">jump</a>
<a href="https://github.com/ofri-peretz/eslint">gh</a>

Configuration Examples

Basic Usage

// eslint.config.js
{
  rules: {
    'conventions/no-raw-cross-property-href': 'error',
  },
}

When Not To Use It

Repositories with a single web property and nothing to cross-link. The rule only pays for itself once two or more properties need joined-up analytics.

Use this rule

npm install -D oxlint-plugin-conventions
.oxlintrc.json
{  "jsPlugins": ["oxlint-plugin-conventions"],  "rules": {    "conventions/no-raw-cross-property-href": "error"  }}
vite.config.ts
import { defineConfig } from 'vite-plus';export default defineConfig({  lint: {    jsPlugins: ['oxlint-plugin-conventions'],    rules: {      'conventions/no-raw-cross-property-href': 'error',    },  },});

oxlint-plugin-conventions re-exports eslint-plugin-conventions/oxlint: the same rules under the same IDs, and no ESLint install. Why oxlint.

Did this rule catch something? Star the repo to get new CWE coverage as we ship it — or follow the AI-code-security benchmarks behind these rules.