MCPInstall

integrate-file-viewer

MUST be used whenever integrating CogniteFileViewer into a Flows app to preview CDF files (PDFs, images, text). Do NOT manually wire up react-pdf or file resolution — this skill handles installation, Vite config, worker setup, and component usage. Triggers: file viewer, file preview, CogniteFileViewer, PDF viewer, view CDF files, document viewer, preview file.

Installs
1.9K
Last 24h
—
Trending rank
—
Security
Not audited

Install

Works with every agent the skills CLI supports.

npx skills add https://github.com/cognitedata/builder-skills --skill integrate-file-viewer
  1. 01

    Install

    Run the command in your project. The CLI asks which agents to install for.

  2. 02

    Describe the task

    Ask your agent for something this skill covers. It loads integrate-file-viewer automatically when relevant.

  3. 03

    Review the result

    The agent follows the SKILL.md steps, scripts and references bundled with the skill.

SKILL.md

The instructions your agent reads when the skill is triggered.

Integrate CogniteFileViewer

Add CogniteFileViewer to this Flows app to preview CDF files (PDF, image, text).

Dependencies

The file-viewer library files (copied in Step 2) require this npm package:

PackageVersion
react-pdf^9.1.1

pdfjs-dist ships as a dependency of react-pdf at the correct version — do not install it separately. react and @cognite/sdk are assumed to already be present in Flows apps.


Your job

Complete these steps in order. Read each file before modifying it.


Step 1 — Understand the app

Read these files before touching anything:

  • package.json — detect package manager (packageManager field or lock file) and existing deps
  • vite.config.ts — understand current Vite setup
  • The component where the viewer should be added

Step 2 — Copy the file-viewer source files

The file-viewer library lives in the code/ directory next to this skill file. Read and copy all files from there into src/cognite-file-viewer/ inside the app:

  • code/types.ts
  • code/mimeTypes.ts
  • code/fileResolution.ts
  • code/useViewport.ts
  • code/useFileResolver.ts
  • code/useDocumentAnnotations.ts
  • code/DocumentAnnotationOverlay.tsx
  • code/CogniteFileViewer.tsx
  • code/index.ts

The PDF.js worker is configured inside CogniteFileViewer.tsx — no separate consumer setup is needed.


Step 3 — Install dependencies

Install react-pdf (see Dependencies above) using the app's package manager:

  • pnpm → pnpm add react-pdf@^9.1.1
  • npm → npm install react-pdf@^9.1.1
  • yarn → yarn add react-pdf@^9.1.1

pnpm users: pnpm's strict linking may prevent the browser from resolving pdfjs-dist. Either add pdfjs-dist as a direct dependency (pnpm add pdfjs-dist), or add public-hoist-pattern[]=pdfjs-dist to .npmrc.


Step 4 — Configure Vite

Add optimizeDeps.exclude: ['pdfjs-dist'] to vite.config.ts to prevent Vite from pre-bundling pdfjs-dist (which breaks the worker):

export default defineConfig({
  // ... existing config ...
  optimizeDeps: {
    exclude: ['pdfjs-dist'],
  },
});

Step 5 — Use the component

Import and render CogniteFileViewer from the locally copied files:

import { CogniteFileViewer } from './cognite-file-viewer';

Get the sdk from the useDune() hook (already available in every Flows app):

import { useDune } from '@cognite/dune';
const { sdk } = useDune();

Supported file types

TypeFormats
PDF.pdf — page navigation, zoom, pan, diagram annotation overlay
Office documentsWord, PowerPoint, Excel, ODS, ODP, ODT, RTF, TSV — converted to PDF via the CDF Document Preview API, then rendered identically to PDF
ImageJPEG, PNG, WebP, SVG, TIFF — zoom, pan, rotation
Text.txt, .csv, .json — rendered as preformatted text
OtherFalls back to renderUnsupported

Minimal usage

This is all you need — zoom, pan, and touch gestures are handled internally:

<CogniteFileViewer
  source={{ type: 'internalId', id: file.id }}
  client={sdk}
  style={{ width: '100%', height: '600px' }}
/>

The component needs a defined height. If the parent has no explicit height, the viewer will collapse to zero. Always set a height via style, className, or the parent container.

File source

Pass any of three source types:

// By instance ID (data-modelled file — enables annotations)
<CogniteFileViewer
  source={{ type: 'instanceId', space: 'my-space', externalId: 'my-file' }}
  client={sdk}
/>

// By CDF internal ID
<CogniteFileViewer
  source={{ type: 'internalId', id: 12345 }}
  client={sdk}
/>

// By direct URL
<CogniteFileViewer
  source={{ type: 'url', url: 'https://...', mimeType: 'application/pdf' }}
/>

Prefer instanceId when available — it's the only source type that enables the diagram annotation overlay. When listing files via sdk.files.list(), check file.instanceId first:

source={
  file.instanceId
    ? { type: 'instanceId', space: file.instanceId.space, externalId: file.instanceId.externalId }
    : { type: 'internalId', id: file.id }
}

Full props reference

<CogniteFileViewer
  // Required
  source={source}
  client={sdk}              // required for instanceId and internalId sources

  // PDF pagination
  page={page}               // controlled current page (1-indexed)
  onPageChange={setPage}
  onDocumentLoad={({ numPages }) => setNumPages(numPages)}

  // Zoom & pan (works on PDF and images)
  zoom={zoom}               // 1 = 100%; Ctrl/Cmd+wheel, pinch-to-zoom, and middle-click drag built in
  onZoomChange={setZoom}
  minZoom={0.25}            // default
  maxZoom={5}               // default
  panOffset={pan}           // controlled pan offset; resets on page change
  onPanChange={setPan}

  // Fit mode
  fitMode="width"           // 'width' fits to container width; 'page' fits entire page in container

  // Rotation (PDFs and images)
  rotation={rotation}       // 0 | 90 | 180 | 270

  // Diagram annotations (instanceId sources only)
  showAnnotations={true}    // default
  onAnnotationClick={(annotation) => { /* annotation.linkedResource has space + externalId */ }}
  onAnnotationHover={(annotation) => {}}

  // Custom annotation tooltip (replaces native <title> tooltip)
  renderAnnotationTooltip={(annotation, rect) => (
    <div style={{
      position: 'absolute',
      left: rect.x + rect.width,
      top: rect.y,
      zIndex: 11,
    }}>
      {annotation.text}
    </div>
  )}

  // Custom overlay (SVG paths, highlights, drawings — works on PDF and images)
  renderOverlay={({ width, height, originalWidth, originalHeight, pageNumber, rotation }) => (
    <svg
      width={width}
      height={height}
      viewBox={`0 0 ${originalWidth} ${originalHeight}`}
      preserveAspectRatio="none"
      style={{ position: 'absolute', top: 0, left: 0, pointerEvents: 'all' }}
    >
      <path d="..." stroke="cyan" fill="none" />
    </svg>
  )}

  // Custom renderers (all optional)
  renderLoading={() => <MySpinner />}
  renderError={(error) => <MyError message={error.message} />}
  renderUnsupported={(mimeType) => <div>Cannot preview {mimeType}</div>}

  // Layout
  className="..."
  style={{ width: '100%', height: '100%' }}
/>

Tips & tricks

Reset page, zoom and rotation when the source changes. The component does not reset these automatically when you switch files — do it yourself:

const navigateToFile = (file: FileInfo) => {
  setSelectedFile(file);
  setPage(1);
  setZoom(1);
  setRotation(0);
};

Gate pagination UI on numPages > 0. onDocumentLoad only fires for PDFs. Don't render pagination controls until you know there are pages to paginate:

{numPages > 0 && (
  <>
    <button disabled={page <= 1} onClick={() => setPage(p => p - 1)}>‹</button>
    <span>{page} / {numPages}</span>
    <button disabled={page >= numPages} onClick={() => setPage(p => p + 1)}>›</button>
  </>
)}

Annotation click → navigate to linked file. annotation.linkedResource contains the space and externalId of the linked CDF instance. Match it against file.instanceId to navigate:

onAnnotationClick={(annotation) => {
  if (!annotation.linkedResource) return;
  const { space, externalId } = annotation.linkedResource;
  const linked = files.find(
    f => f.instanceId?.space === space && f.instanceId?.externalId === externalId
  );
  if (linked) navigateToFile(linked);
}}

Touch support is built in. Two-finger pinch-to-zoom and two-finger drag-to-pan work on touch devices automatically. No configuration needed.

Pan is middle-click drag (when zoomed in) on desktop. Left-click remains free for annotation clicks and text selection.

Ctrl/Cmd + wheel zooms toward the cursor — also built in. Wire zoom/onZoomChange if you want programmatic zoom buttons or to persist zoom state; otherwise it works fully uncontrolled.

renderOverlay receives original page dimensions (originalWidth, originalHeight) so you can set up an SVG viewBox in the original coordinate space. Paths drawn in PDF-point or image-pixel coordinates will map correctly to the rendered page at any zoom level.


Common pitfalls

ProblemCauseFix
Failed to resolve module specifier 'pdf.worker.mjs'pdfjs-dist not hoisted (pnpm)Add public-hoist-pattern[]=pdfjs-dist to .npmrc, or pnpm add pdfjs-dist directly
API version does not match Worker versionpdfjs-dist version mismatch between app and react-pdfDo not install pdfjs-dist separately — let react-pdf provide it. If already installed, remove it
Annotations never showinstanceId is undefined — annotation overlay is disabled without itUse instanceId source, or fall back and accept no annotations for classic files
Annotations show but are emptyFile has no CogniteDiagramAnnotation edges in CDFExpected — only P&ID/diagram files synced to the data model have annotations
Viewer collapses to zero heightParent has no explicit heightSet height via style, className, or parent CSS

FAQ

What does the integrate-file-viewer skill do?

MUST be used whenever integrating CogniteFileViewer into a Flows app to preview CDF files (PDFs, images, text). Do NOT manually wire up react-pdf or file resolution — this skill handles installation, Vite config, worker setup, and component usage. Triggers: file viewer, file preview, CogniteFileViewer, PDF viewer, view CDF files, document viewer, preview file.

How do I install integrate-file-viewer?

Run npx skills add https://github.com/cognitedata/builder-skills --skill integrate-file-viewer in your project. The skills CLI detects the agents you use and copies the skill into the right folder. For Claude Code you can also place the skill folder at ~/.claude/skills/integrate-file-viewer/ (personal) or .claude/skills/integrate-file-viewer/ (project).

Which AI agents can use integrate-file-viewer?

Any agent that supports the open Agent Skills format (a folder with a SKILL.md file), including Claude Code, Codex, Cursor, GitHub Copilot, Gemini CLI, Windsurf, Cline, OpenCode and more.

Is integrate-file-viewer safe to install?

No partner security audit is available yet. Skills can run commands and scripts, so read the SKILL.md and any bundled files before installing.

Who maintains integrate-file-viewer?

It is published by cognitedata in cognitedata/builder-skills. It has 1,903 recorded installs.

More from cognitedata/builder-skills

View all →

skill-creator

cognitedata/builder-skills

Create new skills, modify and improve existing skills, and measure skill performance. Use when users want to create a skill from scratch for Claude Code or Cursor, update or optimize an existing skill, run evals to test a skill, benchmark skill performance with variance analysis, or optimize a skill's description for better triggering accuracy.

AI & Agents2.5K installs

code-quality

cognitedata/builder-skills

MUST be used whenever reviewing a Flows app for code quality, maintainability, or clean code issues — before a PR review, after a feature is complete, or when the user asks for a code review. Do NOT skip linting steps. Triggers: code quality, code review, clean code, refactor, maintainability, technical debt, any type, naming, dead code, duplication, DRY, single responsibility, component size, lint, linting, TypeScript strict, dependency injection, file structure.

test-coverage

cognitedata/builder-skills

MUST be used whenever fixing test coverage for a Flows app to meet the 80% line coverage hard gate. This skill finds AND fixes coverage gaps — it configures tooling, writes missing tests, covers untested paths, and refactors code for testability. It does not just report. Triggers: test coverage, fix tests, write tests, add tests, coverage fix, 80% coverage, coverage gate, missing tests, testability, vitest coverage, jest coverage.

Testing & QA1.9K installs

dependencies-audit

cognitedata/builder-skills

MUST be used whenever fixing dependency issues in a Flows app. This skill finds AND fixes vulnerabilities, outdated packages, deprecated dependencies, and license issues — it does not just report them. Triggers: dependencies, packages, fix dependencies, update packages, fix vulnerabilities, npm audit fix, pnpm audit fix, CVE fix, outdated, deprecated, supply chain, license.

Security1.9K installs

design

cognitedata/builder-skills

Simplified Aura guidance for selecting primitives, keeping token usage consistent, and applying reliable layout/copy/state patterns in Flows and Fusion apps.

Frontend & Design1.9K installs

reveal-3d

cognitedata/builder-skills

Integrates the @cognite/reveal-widget npm package into Flows apps for an interactive Cognite Reveal 3D Scene/CAD/point cloud/360-image viewer. Use when adding 3D viewer, 3D visualization, Reveal, CAD model, Point cloud model, 360 image collection, Scenes, RevealWidget, RevealWidgetController, DM 3D mapping, asset 3D model, model browser, or Cognite 3D content to a Flows application.

Media & Creative1.9K installs

Popular frontend & design skills

View category →

setup-matt-pocock-skills

mattpocock/skills

Configure this repo for the engineering skills: set up its issue tracker, triage label vocabulary, and domain doc layout. Run once before first use of the other engineering skills.

Frontend & Design1.1M installs

frontend-design

anthropics/skills

Guidance for distinctive, intentional visual design when building new UI or reshaping an existing one. Helps with aesthetic direction, typography, and making choices that don't read as templated defaults.

OfficialFrontend & Design1M installs

hyperframes-animation

heygen-com/hyperframes

All animation knowledge for HyperFrames — atomic motion rules, multi-phase scene blueprints, scene transitions, broader motion-design techniques, AND the seven runtime adapters (GSAP default, plus Lottie, Three.js, Anime.js, CSS keyframes, Web Animations API, TypeGPU). Use for any motion or animation task: pick 2-4 rules and compose, or load a blueprint, or look up runtime-specific API (e.g. GSAP eases / Lottie player / Three.js mixer). Also covers auditing an existing composition's choreography (animation map) and 24 named text-animation effects. HyperFrames-native: single paused timeline, seek-safe, deterministic.

prototype

mattpocock/skills

Build a throwaway prototype to answer a design question. Use when the user wants to sanity-check whether a state model or logic feels right, or explore what a UI should look like.

Frontend & Design999.2K installs

hyperframes-core

heygen-com/hyperframes

The HyperFrames composition contract — build one renderable project. Use for composition structure, the data- timing attributes, class="clip", tracks, sub-compositions, variables, framework-owned media playback, deterministic-render rules, and validation. Read before writing composition HTML.

Frontend & Design930.5K installs

vercel-react-best-practices

vercel-labs/agent-skills

React and Next.js performance optimization guidelines from Vercel Engineering. This skill should be used when writing, reviewing, or refactoring React/Next.js code to ensure optimal performance patterns. Triggers on tasks involving React components, Next.js pages, data fetching, bundle optimization, or performance improvements.

OfficialFrontend & Design843.1K installs