Feature View-Only Mode¶
This document explains how to implement view-only mode for features that are not included in an organization's subscription.
Overview¶
When an organization doesn't have access to a feature, you can now allow them to view the content (read-only) while displaying a badge indicating that the feature is not included in their subscription.
Components¶
1. FeatureViewOnlyBadge¶
A badge component that displays "View Only" when a feature is not enabled. It includes a tooltip explaining that the feature is not included in the subscription.
Usage in page headers:
import { FeatureViewOnlyBadge } from "@/components/FeatureViewOnlyBadge";
<div className="flex items-center gap-2">
<h1>Projects</h1>
<FeatureViewOnlyBadge feature="projects" />
</div>
2. FeatureGate with allowViewOnly¶
The existing FeatureGate component now supports an allowViewOnly prop that allows viewing even when the feature is disabled.
Usage:
import { FeatureGate } from "@/components/FeatureGate";
<FeatureGate feature="projects" allowViewOnly={true}>
<ProjectsPage />
</FeatureGate>
When allowViewOnly={true}:
- The page is accessible even if the feature is disabled
- A sticky badge banner appears at the top of the page
- Interactive elements should be wrapped with FeatureViewOnlyWrapper to disable them
3. FeatureViewOnlyGate¶
A simpler alternative that always allows viewing with a badge when the feature is disabled.
Usage:
import { FeatureViewOnlyGate } from "@/components/FeatureViewOnlyGate";
<FeatureViewOnlyGate feature="projects">
<ProjectsPage />
</FeatureViewOnlyGate>
4. FeatureViewOnlyWrapper¶
Wraps interactive elements (buttons, forms, etc.) to disable them when in view-only mode.
Usage:
import { FeatureViewOnlyWrapper } from "@/components/FeatureViewOnlyWrapper";
<FeatureViewOnlyWrapper>
<Button onClick={handleCreate}>Create Project</Button>
</FeatureViewOnlyWrapper>
5. useFeatureViewOnly Hook¶
A hook to check if the current feature is in view-only mode.
Usage:
import { useFeatureViewOnly } from "@/components/FeatureGate";
function MyComponent {
const { isViewOnly } = useFeatureViewOnly;
return (
<Button disabled={isViewOnly}>
Edit
</Button>
);
}
Complete Example¶
Here's a complete example of a page with view-only support:
import { FeatureGate } from "@/components/FeatureGate";
import { FeatureViewOnlyBadge } from "@/components/FeatureViewOnlyBadge";
import { FeatureViewOnlyWrapper } from "@/components/FeatureViewOnlyWrapper";
function ProjectsPage {
return (
<div>
{/* Header with badge */}
<div className="flex items-center gap-2">
<h1>Projects</h1>
<FeatureViewOnlyBadge feature="projects" />
</div>
{/* Interactive button wrapped to disable in view-only */}
<FeatureViewOnlyWrapper>
<Button onClick={handleCreate}>Create Project</Button>
</FeatureViewOnlyWrapper>
{/* Rest of the page content */}
</div>
);
}
// In your route definition:
<FeatureGate feature="projects" allowViewOnly={true}>
<ProjectsPage />
</FeatureGate>
Best Practices¶
- Always show the badge in the page header when using view-only mode
- Wrap interactive elements with
FeatureViewOnlyWrapperto prevent actions - Use the sticky banner from
FeatureGateorFeatureViewOnlyGatefor prominent visibility - Provide clear messaging - the badge tooltip explains the limitation
- Consider UX - view-only mode should still provide value by showing what's available
Migration Guide¶
To convert an existing feature to support view-only mode:
-
Update the route to use
allowViewOnly={true}: -
Add the badge to the page header:
-
Wrap interactive elements:
-
Test with a restricted organization to verify the badge appears and interactions are disabled.