> For the complete documentation index, see [llms.txt](https://docs.wellcomecollection.org/request-for-comments-rfcs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.wellcomecollection.org/request-for-comments-rfcs/086-item-viewer-refactor/05-feature-flag-strategy.md).

# Feature Flag Strategy

[← Back to Index](/request-for-comments-rfcs/086-item-viewer-refactor.md)

**Approach:** Build refactored version alongside existing code, controlled by a feature flag. Load entirely different components based on toggle status rather than conditionals within components.

## Why Feature Flag?

1. **Safe rollout** - Users can opt in, test, provide feedback
2. **Instant rollback** - Disable flag if issues arise (no deploy needed)
3. **Production testing** - Validate with real traffic before making it the default
4. **Clean code** - No conditionals littering components
5. **Comparison** - Users can toggle between old/new to compare
6. **Team confidence** - Ship changes knowing you can revert instantly

## Component Structure

```
content/webapp/
├── contexts/
│   ├── ItemViewerContext/           # LEGACY - unchanged
│   │   └── index.tsx
│   └── ItemViewerContextV2/         # NEW - refactored version
│       ├── index.tsx
│       ├── ItemViewerContextV2.test.tsx
│       └── test-utils.ts
│
├── views/pages/works/work/IIIFViewer/
    ├── index.tsx                    # Wrapper - loads old OR new based on flag
    ├── IIIFViewer.legacy.tsx        # Uses ItemViewerContext (old)
    ├── IIIFViewer.refactored.tsx    # Uses ItemViewerContextV2 (new)
    ├── ViewerTopBar.legacy.tsx
    ├── ViewerTopBar.refactored.tsx
    ├── ZoomedImage.legacy.tsx
    ├── ZoomedImage.refactored.tsx
    └── ...
```

**Key insight:** Legacy and refactored versions use different contexts entirely. This means:

* Zero risk to existing implementation
* Can develop new context in isolation
* Can test both versions independently
* Clean deletion when feature flag removed

## Usage Pattern

```typescript
// content/webapp/views/pages/works/work/IIIFViewer/index.tsx
import dynamic from 'next/dynamic';
import { useToggles } from '@weco/toggles/webapp/hooks';
import { IIIFViewerProps } from './types';

// Important: dynamic() server-renders by default
// Do NOT add { ssr: false } as this would break NoScriptImage functionality
const IIIFViewerLegacy = dynamic(() => import('./IIIFViewer.legacy'));
const IIIFViewerRefactored = dynamic(() => import('./IIIFViewer.refactored'));

export default function IIIFViewer(props: IIIFViewerProps) {
  const { iiifViewerRefactored } = useToggles();
  
  if (iiifViewerRefactored) {
    return <IIIFViewerRefactored {...props} />;
  }
  
  return <IIIFViewerLegacy {...props} />;
}
```

## Flag Configuration

**File:** `toggles/webapp/app/toggles.ts`

```typescript
export const toggles = {
  // ... existing toggles ...
  iiifViewerRefactored: {
    id: 'iiifViewerRefactored',
    title: 'IIIF Viewer - Refactored Context',
    defaultValue: false, // Start disabled
    description: 'Use refactored ItemViewerContext with centralised derived values',
  },
};
```

## Rollout Plan

### Phase 1: Development

* Feature flag OFF by default
* Developers can enable for testing
* All automated tests must pass with flag ON and OFF

### Phase 2: Internal Testing

* Enable for team members to verify functionality
* Test with real data on staging/production

### Phase 3: Default to ON

* Make toggle publicly available
* Continue monitoring

### Phase 4: Cleanup

* After toggle defaulting to ON for 1+ week with no issues
* Remove feature flag entirely
* Delete `.legacy.tsx` files
* Rename `.refactored.tsx` to `.tsx`
* Delete `ItemViewerContext` (old context)
* Rename `ItemViewerContextV2` to `ItemViewerContext`

***

**Next:** [06 - Phase 0: Type Audit](/request-for-comments-rfcs/086-item-viewer-refactor/06-phase-0-type-audit.md)


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.wellcomecollection.org/request-for-comments-rfcs/086-item-viewer-refactor/05-feature-flag-strategy.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
