Skip to content

Enable useUniqueElementIds rule and fix all static ID violations (erd-core package) #3274

@FunamaYukina

Description

@FunamaYukina

Overview

The useUniqueElementIds biome rule needs to be enabled for the @liam-hq/erd-core package to prevent duplicate IDs in SVG components and other elements. After enabling this rule, lint errors have been detected that need to be fixed.

Alternative Approach (Recommended)

Given that ERD instances are typically rendered once per page and multiple simultaneous ERD instances are a rare use case, an alternative simpler approach could be considered:

Option: Keep Static IDs with Inline Ignore Comments

Instead of implementing dynamic IDs with useId() and Context API, we could keep static IDs and use inline ignore comments for specific violations:

// biome-ignore lint/nursery/useUniqueElementIds: ERD is designed for single instance per page
<marker id="zeroOrOneLeft">
  {/* ... */}
</marker>

// biome-ignore lint/nursery/useUniqueElementIds: SVG gradient used in single ERD instance
<radialGradient id="myGradient">
  {/* ... */}
</radialGradient>

Rationale:

  • ERD is designed to be used as a single instance per page
  • The added complexity of dynamic IDs (Context API, useId hooks, etc.) may be over-engineering for the actual use case
  • Static IDs make testing and debugging easier
  • Performance is slightly better without the overhead of ID generation
  • Code remains simpler and more maintainable
  • Rule remains enabled globally while allowing specific exceptions

Trade-offs:

  • ✅ Simpler implementation and maintenance
  • ✅ Better performance
  • ✅ Easier testing
  • ✅ Rule remains enabled for other cases
  • ❌ Won't support multiple ERD instances on the same page (rare use case)
  • ❌ Requires manual ignore comments

Original Approach: Dynamic IDs Implementation

Steps to Enable the Rule

  1. Update frontend/packages/erd-core/biome.jsonc with the following configuration:
{
  "extends": "//",
  "root": false,
  "linter": {
    "rules": {
      "nursery": {
        "useUniqueElementIds": "error"
      },
      "correctness": {
        "noNodejsModules": "error"
      }
    }
  },
  "overrides": [
    {
      "includes": ["*.config.ts", "*.config.js"],
      "linter": {
        "rules": {
          "correctness": {
            "noNodejsModules": "off"
          }
        }
      }
    }
  ]
}

Note: The existing correctness.noNodejsModules configuration and overrides should be preserved.

This overrides the base configuration in frontend/internal-packages/configs/biome.jsonc where useUniqueElementIds is set to "off".

  1. Run lint to see the errors:
cd frontend/packages/erd-core && pnpm lint:biome

Lint Errors to Fix

After enabling the rule, multiple useUniqueElementIds errors appear across various components in the erd-core package. These errors occur where static string literals are used for ID attributes instead of dynamically generated unique IDs.

Root Cause

Components throughout the erd-core package are using hardcoded IDs for SVG elements and other components. This is particularly problematic in ERD contexts because:

  • ERD diagrams can render multiple instances of the same component types
  • SVG marker definitions and references require unique IDs
  • Complex ERD layouts may duplicate component instances

When these components are rendered multiple times, it creates duplicate IDs in the DOM, leading to rendering issues and violating HTML specifications.

Required Fix Pattern

Replace static IDs with dynamically generated ones using React's useId() hook:

import { useId } from 'react'

export const SomeERDComponent = () => {
  const elementId = useId()
  const markerId = useId()
  
  return (
    <div>
      {/* For HTML elements */}
      <div id={elementId}>...</div>
      
      {/* For SVG elements */}
      <svg>
        <defs>
          <marker id={markerId}>
            {/* ... */}
          </marker>
        </defs>
        <path markerEnd={`url(#${markerId})`} />
      </svg>
    </div>
  )
}

Important: Ensure that any SVG elements referencing these IDs (e.g., url(#id) in path elements, clipPath, marker references) are also updated to use the dynamic IDs.

Action Items

Choose one of the following approaches:

If choosing Alternative Approach (Inline Ignore):

  • Enable the useUniqueElementIds: "error" rule in frontend/packages/erd-core/biome.jsonc
  • Run pnpm lint:biome to identify all components with static ID violations
  • Add inline // biome-ignore lint/nursery/useUniqueElementIds: [reason] comments for each violation
  • Ensure ignore comments include clear reasoning
  • Run pnpm lint to ensure all errors are resolved
  • Close related PR if dynamic IDs were already implemented

If choosing Original Approach (Dynamic IDs):

  • Enable the useUniqueElementIds: "error" rule in frontend/packages/erd-core/biome.jsonc
  • Run pnpm lint:biome to identify all components with static ID violations
  • Fix all useUniqueElementIds errors by replacing static IDs with useId() generated IDs
  • Update all references to these IDs (SVG url() references, htmlFor, etc.)
  • Run pnpm lint to ensure all errors are resolved
  • Test ERD rendering with multiple components to ensure they display correctly
  • Verify that all ERD functionality (interactions, hover states, etc.) still works

Testing

After implementing the chosen approach:

  1. All lint errors should be resolved (or properly ignored)
  2. ERD diagrams should render correctly with relationships and components
  3. SVG elements should display properly with correct markers and styling
  4. All ERD interactions should work as expected
  5. No visual regression in ERD rendering

Related

Metadata

Metadata

Assignees

Labels

claude-create-prTrigger Claude AI to automatically implement this issue and create a PR

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions