npm.io
0.27.0 • Published 5d ago

@roottale/cms-media

Licence
UNLICENSED
Version
0.27.0
Deps
0
Size
63 kB
Vulns
0
Weekly
33

@roottale/cms-media

RootTale 미디어 패키지 — R2 원본 보관 + CF Images variants + 한글 파일명 정규화 + CfImage 렌더 컴포넌트. (ADR-0034 §3, docs/image-standard.md)

두 엔트리:

  • @roottale/cms-media — 서버(R2/S3 클라이언트, variant URL 생성, 파일명 정규화). Node.
  • @roottale/cms-media/react — 클라이언트 CfImage 렌더 컴포넌트("use client"). react는 optional peer.

CfImage (@roottale/cms-media/react)

next/image 대체. CF Images는 이미 variant(sm/md/lg, 자동 webp/avif)를 제공하므로 브라우저가 직접 받게 한다 → Vercel 이미지 최적화 함수(/_next/image, Fluid Compute) 비용 0.

import { CfImage } from "@roottale/cms-media/react";

<div style={{ position: "relative", height: 160 }}>
  <CfImage src={coverUrl} alt="단지 조감도" fill sizes="(max-width:600px) 100vw, 400px" />
</div>
  • CF imagedelivery URL이면 sm/md/lg srcset 자동, 기본 src /md. 비-CF(로컬 SVG·외부)면 변형 없이 그대로.
  • placeholder(로더): 'blur'(기본) | 'skeleton'(shimmer) | 'image' | 'none'. 로딩 중 표시 후 onLoad 페이드인.
    • 'blur'(CF): skeleton shimmer를 즉시 깔아 마운트 순간부터 로딩을 인지시키고, CF thumbnail이 받아지는 순간 그 위로 흐림을 페이드인 → 원본 도착 시 둘 다 페이드아웃. (blur 썸네일도 네트워크라 받기 전 빈 화면 갭을 skeleton이 메움. CF가 아니면 skeleton 단독.)
    • 'image' + loaderImage="<url>": 로딩 중 가운데 커스텀 이미지(브랜드 스피너/로고 등).
    • loader={<MySpinner/>}: 임의 ReactNode를 로더로 직접 주입(최우선). loaderBackground로 배경색 지정.
  • priority로 LCP 즉시 로드. fill/sizes/width/height/loading/onError/style 등 next/image·<img> 호환.
  • "use client" — 서버 컴포넌트에서도 직접 렌더 가능(자체 클라이언트 경계).

import Image from "@roottale/cms-media/react"(default)로 받아 기존 next/image 호출부를 그대로 두는 drop-in 교체도 가능.

서버 헬퍼 (@roottale/cms-media)

  • variantUrl(config, imageId, variant) / allVariantUrls — image id 기반 variant URL.
  • cfImageVariant(url, variant) / cfImageSrcSet(url) / isCfImageUrl(url) — full delivery URL 변형 교체(렌더용, server/client 공용).
  • r2KeyForTenant, normalizeFilename, R2/S3 클라이언트 인터페이스 — 업로드(R2 원본 → CF Images upload-via-URL) 구현용.

변형명/픽셀: thumbnail 96 · sm 320 · md 768 · lg 1600 (ADR-0034 §7.1.1).

Keywords