Skip to content

Enable noImgElement biome rule for @liam-hq/ui package #3419

@FunamaYukina

Description

@FunamaYukina

Overview

The noImgElement biome rule needs to be enabled for the @liam-hq/ui package to improve performance by replacing <img> elements with optimized image components. After enabling this rule, lint errors have been detected that need to be fixed.

Steps to Enable the Rule

  1. Update frontend/packages/ui/biome.jsonc with the following configuration:
{
  "extends": "//",
  "root": false,
  "linter": {
    "rules": {
      "performance": {
        "noImgElement": "error"
      }
    }
  }
}

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

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

Lint Errors to Fix

After enabling the rule, noImgElement errors appear in the following file:

  • src/components/Avatar/AvatarWithImage.tsx

These violations can lead to:

  • Slower LCP (Largest Contentful Paint) scores across all consuming applications
  • Higher bandwidth usage for avatar images
  • Missing automatic image optimization
  • Poor performance on slow networks

Root Cause

The UI component contains <img> elements that should be replaced with optimized image components. Since this is a UI library package, it needs a solution that works across different consuming applications (some may not use Next.js).

Required Fix Patterns

Option 1: Create a Generic Optimized Image Component

// Create src/components/Image/Image.tsx
interface ImageProps {
  src: string;
  alt: string;
  className?: string;
  width?: number;
  height?: number;
}

export const Image = ({ src, alt, className, width, height }: ImageProps) => {
  // Implement optimized image loading logic
  return <img src={src} alt={alt} className={className} loading="lazy" />
}

// Then use in AvatarWithImage
import { Image } from '../Image/Image'
<Image src={src} alt={alt} className={styles.image} />

Option 2: Accept Image Component as Prop

interface AvatarWithImageProps {
  ImageComponent?: React.ComponentType<{src: string, alt: string, className?: string}>;
  // ... other props
}

const AvatarWithImage = ({ ImageComponent = 'img', ...props }) => {
  return <ImageComponent src={src} alt={alt} className={styles.image} />
}

Action Items

  • Enable the noImgElement: "error" rule in frontend/packages/ui/biome.jsonc
  • Run pnpm lint:biome to identify all <img> element violations
  • Design a solution for optimized images in a UI library context
  • Replace <img> elements in:
    • src/components/Avatar/AvatarWithImage.tsx
  • Run pnpm lint to verify all errors are resolved
  • Test the component in consuming applications (app, docs, storybook)
  • Ensure backward compatibility is maintained

Testing

After implementing all fixes:

  1. All lint errors should be resolved
  2. Avatar images should display correctly in all consuming apps
  3. Performance should be improved with optimized image loading
  4. No breaking changes should be introduced to the public API
  5. Storybook stories should continue to work properly

Related

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions