0
# Features
1
2
The @strapi/helper-plugin package provides 10 feature contexts and hooks that manage core application functionality including app information, notifications, permissions, tracking, and plugin extensibility. These features provide the foundation for building integrated Strapi plugins.
3
4
## App Information
5
6
Context and hook for accessing Strapi application metadata and environment information.
7
8
```typescript { .api }
9
// App information context
10
interface AppInfoContextValue {
11
autoReload?: boolean;
12
communityEdition?: boolean;
13
currentEnvironment?: string;
14
dependencies?: Record<string, string>;
15
latestStrapiReleaseTag?: string;
16
nodeVersion?: string;
17
projectId?: string | null;
18
setUserDisplayName: (name: string) => void;
19
shouldUpdateStrapi: boolean;
20
strapiVersion?: string | null;
21
useYarn?: boolean;
22
userDisplayName: string;
23
userId?: string;
24
}
25
26
// Hook for app information
27
function useAppInfo(): AppInfoContextValue | {};
28
29
// Provider component
30
interface AppInfoProviderProps extends AppInfoContextValue {
31
children: React.ReactNode;
32
}
33
function AppInfoProvider(props: AppInfoProviderProps): JSX.Element;
34
35
// React context instance
36
const AppInfoContext: React.Context<AppInfoContextValue | {}>;
37
```
38
39
**Usage Examples:**
40
41
```typescript
42
// Access app information
43
const {
44
strapiVersion,
45
shouldUpdateStrapi,
46
currentEnvironment,
47
setUserDisplayName
48
} = useAppInfo();
49
50
// Display version information
51
if (shouldUpdateStrapi) {
52
// Show update notification
53
}
54
55
// Update user display name
56
const handleNameChange = (newName: string) => {
57
setUserDisplayName(newName);
58
};
59
```
60
61
## Auto-Reload Overlay Blocker
62
63
Context and hook for managing auto-reload blocking during critical operations.
64
65
```typescript { .api }
66
// Auto-reload overlay blocker hook
67
interface AutoReloadOverlayBlockerReturn {
68
lockAppWithAutoreload?: () => void;
69
unlockAppWithAutoreload?: () => void;
70
}
71
72
function useAutoReloadOverlayBlocker(): AutoReloadOverlayBlockerReturn;
73
74
// Provider component
75
interface AutoReloadOverlayBlockerProviderProps {
76
children: React.ReactNode;
77
}
78
function AutoReloadOverlayBlockerProvider(props: AutoReloadOverlayBlockerProviderProps): JSX.Element;
79
```
80
81
**Usage Examples:**
82
83
```typescript
84
// Block auto-reload during operations
85
const { lockAppWithAutoreload, unlockAppWithAutoreload } = useAutoReloadOverlayBlocker();
86
87
const handleCriticalOperation = async () => {
88
lockAppWithAutoreload?.();
89
try {
90
await performCriticalOperation();
91
} finally {
92
unlockAppWithAutoreload?.();
93
}
94
};
95
```
96
97
## Custom Fields
98
99
Context and hook for managing custom field registry and components.
100
101
```typescript { .api }
102
// Custom fields hook
103
interface CustomFieldsReturn {
104
get: (uid: string) => CustomFieldServerSide | undefined;
105
}
106
107
function useCustomFields(): CustomFieldsReturn;
108
109
// Provider component
110
interface CustomFieldsProviderProps {
111
children: React.ReactNode;
112
customFields?: Record<string, CustomFieldServerSide>;
113
}
114
function CustomFieldsProvider(props: CustomFieldsProviderProps): JSX.Element;
115
116
// Custom field interface
117
interface CustomFieldServerSide {
118
name: string;
119
pluginId?: string;
120
type: string;
121
icon?: React.ComponentType;
122
intlLabel: {
123
id: string;
124
defaultMessage: string;
125
};
126
intlDescription: {
127
id: string;
128
defaultMessage: string;
129
};
130
components: {
131
Input: React.ComponentType<any>;
132
};
133
options?: {
134
base?: Array<{
135
sectionTitle: { id: string; defaultMessage: string } | null;
136
items: Array<{
137
intlLabel: { id: string; defaultMessage: string };
138
name: string;
139
type: string;
140
value?: any;
141
}>;
142
}>;
143
advanced?: Array<{
144
sectionTitle: { id: string; defaultMessage: string } | null;
145
items: Array<{
146
intlLabel: { id: string; defaultMessage: string };
147
name: string;
148
type: string;
149
value?: any;
150
}>;
151
}>;
152
validator?: (args: any) => any;
153
};
154
}
155
```
156
157
**Usage Examples:**
158
159
```typescript
160
// Access custom fields registry
161
const { get } = useCustomFields();
162
163
const customField = get('plugin::my-plugin.color-picker');
164
165
if (customField) {
166
const { Input } = customField.components;
167
// Render custom field component
168
}
169
```
170
171
## Guided Tour
172
173
Context and hook for managing guided tour state and navigation.
174
175
```typescript { .api }
176
// Guided tour context
177
interface GuidedTourContextValue {
178
currentStep: GuidedTourStep | null;
179
guidedTourState: {
180
contentTypeBuilder: {
181
create: boolean;
182
success: boolean;
183
};
184
contentManager: {
185
create: boolean;
186
success: boolean;
187
};
188
apiTokens: {
189
create: boolean;
190
success: boolean;
191
};
192
transferTokens: {
193
create: boolean;
194
success: boolean;
195
};
196
};
197
isGuidedTourVisible: boolean;
198
isSkipped: boolean;
199
setCurrentStep: (step: GuidedTourStep | null) => void;
200
setGuidedTourVisibility: (isVisible: boolean) => void;
201
setSkipped: (isSkipped: boolean) => void;
202
setStepState: (step: GuidedTourStep, state: boolean) => void;
203
startSection: (section: GuidedTourSectionKey) => void;
204
}
205
206
// Hook for guided tour
207
function useGuidedTour(): GuidedTourContextValue;
208
209
// Provider component
210
interface GuidedTourProviderProps extends GuidedTourContextValue {
211
children: React.ReactNode;
212
}
213
function GuidedTourProvider(props: GuidedTourProviderProps): JSX.Element;
214
215
// Step types
216
type GuidedTourStep = `${GuidedTourSectionKey}.${GuidedTourStepKey}`;
217
type GuidedTourSectionKey = 'contentTypeBuilder' | 'contentManager' | 'apiTokens' | 'transferTokens';
218
type GuidedTourStepKey = 'create' | 'success';
219
```
220
221
**Usage Examples:**
222
223
```typescript
224
// Access guided tour state
225
const {
226
currentStep,
227
isGuidedTourVisible,
228
setCurrentStep,
229
setStepState,
230
startSection
231
} = useGuidedTour();
232
233
// Start a guided tour section
234
const handleStartTour = () => {
235
startSection('contentTypeBuilder');
236
setCurrentStep('contentTypeBuilder.create');
237
};
238
239
// Complete a tour step
240
const handleStepComplete = () => {
241
setStepState('contentTypeBuilder.create', true);
242
setCurrentStep('contentTypeBuilder.success');
243
};
244
```
245
246
## Library
247
248
Context and hook for managing component library and registry.
249
250
```typescript { .api }
251
// Library hook
252
interface LibraryFields {
253
[key: string]: React.ComponentType<any>;
254
}
255
256
interface LibraryReturn {
257
fields: LibraryFields;
258
}
259
260
function useLibrary(): LibraryReturn;
261
262
// Provider component
263
interface LibraryProviderProps {
264
children: React.ReactNode;
265
fields?: LibraryFields;
266
}
267
function LibraryProvider(props: LibraryProviderProps): JSX.Element;
268
```
269
270
**Usage Examples:**
271
272
```typescript
273
// Access registered components
274
const { fields } = useLibrary();
275
276
const CustomInput = fields['my-custom-input'];
277
278
if (CustomInput) {
279
return <CustomInput {...props} />;
280
}
281
```
282
283
## Notifications
284
285
Context and hooks for displaying toast notifications to users.
286
287
```typescript { .api }
288
// Notification configuration
289
interface NotificationConfig {
290
blockTransition?: boolean;
291
link?: NotificationLink;
292
message?: string | TranslationMessage;
293
onClose?: () => void;
294
timeout?: number;
295
title?: string | TranslationMessage;
296
type?: 'info' | 'warning' | 'softWarning' | 'success';
297
}
298
299
// Notification link
300
interface NotificationLink {
301
label: string | MessageDescriptor;
302
target?: string;
303
url: string;
304
}
305
306
// Hook for notifications
307
function useNotification(): (config: NotificationConfig) => void;
308
309
// Provider component
310
interface NotificationsProviderProps {
311
children: React.ReactNode;
312
}
313
function NotificationsProvider(props: NotificationsProviderProps): JSX.Element;
314
315
// Context value
316
interface NotificationsContextValue {
317
toggleNotification: (config: NotificationConfig) => void;
318
}
319
const NotificationsContext: React.Context<NotificationsContextValue>;
320
```
321
322
**Usage Examples:**
323
324
```typescript
325
// Display notifications
326
const toggleNotification = useNotification();
327
328
// Success notification
329
toggleNotification({
330
type: 'success',
331
message: 'Data saved successfully!'
332
});
333
334
// Error notification with link
335
toggleNotification({
336
type: 'warning',
337
message: 'Failed to save data',
338
link: {
339
label: 'View documentation',
340
url: '/docs/troubleshooting'
341
},
342
timeout: 5000
343
});
344
345
// Custom notification with callback
346
toggleNotification({
347
type: 'info',
348
message: 'Processing...',
349
blockTransition: true,
350
onClose: () => {
351
console.log('Notification closed');
352
}
353
});
354
```
355
356
## Overlay Blocker
357
358
Context and hook for managing overlay blocking during operations.
359
360
```typescript { .api }
361
// Overlay blocker hook
362
interface OverlayBlockerReturn {
363
lockApp?: () => void;
364
unlockApp?: () => void;
365
}
366
367
function useOverlayBlocker(): OverlayBlockerReturn;
368
369
// Provider component
370
interface OverlayBlockerProviderProps {
371
children: React.ReactNode;
372
}
373
function OverlayBlockerProvider(props: OverlayBlockerProviderProps): JSX.Element;
374
```
375
376
**Usage Examples:**
377
378
```typescript
379
// Block UI during operations
380
const { lockApp, unlockApp } = useOverlayBlocker();
381
382
const handleLongOperation = async () => {
383
lockApp?.();
384
try {
385
await performLongOperation();
386
} finally {
387
unlockApp?.();
388
}
389
};
390
```
391
392
## RBAC (Role-Based Access Control)
393
394
Context and hook for managing user permissions and role-based access.
395
396
```typescript { .api }
397
// Permission interface
398
interface Permission {
399
id?: Entity.ID;
400
action: string;
401
actionParameters?: object;
402
subject?: string | null;
403
properties?: {
404
fields?: string[];
405
locales?: string[];
406
[key: string]: any;
407
};
408
conditions?: string[];
409
}
410
411
// RBAC context value
412
interface RBACContextValue {
413
allPermissions: Permission[];
414
refetchPermissions: () => void;
415
}
416
417
// Hook for RBAC
418
function useRBAC(): RBACContextValue;
419
function useRBACProvider(): RBACContextValue; // Alias
420
421
// Context instance
422
const RBACContext: React.Context<RBACContextValue>;
423
```
424
425
**Usage Examples:**
426
427
```typescript
428
// Access user permissions
429
const { allPermissions, refetchPermissions } = useRBAC();
430
431
// Check specific permissions
432
const canCreate = allPermissions.some(
433
permission => permission.action === 'create' && permission.subject === 'api::article.article'
434
);
435
436
// Refresh permissions after role changes
437
const handleRoleUpdate = async () => {
438
await updateUserRole();
439
refetchPermissions();
440
};
441
```
442
443
## Strapi App
444
445
Context and hook for managing core Strapi application state and functionality.
446
447
```typescript { .api }
448
// Strapi app hook
449
interface StrapiAppReturn {
450
// Core app functionality (implementation varies)
451
[key: string]: any;
452
}
453
454
function useStrapiApp(): StrapiAppReturn;
455
456
// Provider component
457
interface StrapiAppProviderProps {
458
children: React.ReactNode;
459
}
460
function StrapiAppProvider(props: StrapiAppProviderProps): JSX.Element;
461
```
462
463
**Usage Examples:**
464
465
```typescript
466
// Access Strapi app context
467
const strapiApp = useStrapiApp();
468
469
// Use app-level functionality
470
// (specific APIs depend on implementation)
471
```
472
473
## Tracking
474
475
Context and hook for analytics and event tracking.
476
477
```typescript { .api }
478
// Telemetry properties
479
interface TelemetryProperties {
480
useTypescriptOnServer?: boolean;
481
useTypescriptOnAdmin?: boolean;
482
isHostedOnStrapiCloud?: boolean;
483
numberOfAllContentTypes?: number;
484
numberOfComponents?: number;
485
numberOfDynamicZones?: number;
486
}
487
488
// Tracking context value
489
interface TrackingContextValue {
490
uuid?: string | boolean;
491
deviceId?: string;
492
telemetryProperties?: TelemetryProperties;
493
}
494
495
// Tracking hook return
496
interface UseTrackingReturn {
497
trackUsage<TEvent extends TrackingEvent>(
498
event: TEvent['name'],
499
properties?: TEvent['properties']
500
): Promise<null | AxiosResponse<string>>;
501
}
502
503
// Hook for tracking
504
function useTracking(): UseTrackingReturn;
505
506
// Provider component
507
interface TrackingProviderProps {
508
children: React.ReactNode;
509
value?: TrackingContextValue;
510
}
511
function TrackingProvider(props: TrackingProviderProps): JSX.Element;
512
513
// Event types (extensive list of predefined events)
514
type TrackingEvent = EventWithoutProperties | EventsWithProperties;
515
```
516
517
**Usage Examples:**
518
519
```typescript
520
// Track user events
521
const { trackUsage } = useTracking();
522
523
// Track simple events
524
trackUsage('didCreateEntry');
525
526
// Track events with properties
527
trackUsage('didFilterEntries', {
528
useRelation: true
529
});
530
531
// Track navigation events
532
trackUsage('willNavigate', {
533
from: '/admin/plugins',
534
to: '/admin/content-manager'
535
});
536
537
// Track content operations
538
trackUsage('didEditEntry', {
539
status: 'draft',
540
error: null
541
});
542
```
543
544
## Integration Patterns
545
546
### Feature Composition
547
548
```typescript
549
// Combine multiple features in a plugin
550
const MyPlugin = () => {
551
const { trackUsage } = useTracking();
552
const toggleNotification = useNotification();
553
const { canCreate } = useRBAC();
554
const { lockApp, unlockApp } = useOverlayBlocker();
555
556
const handleCreateAction = async () => {
557
if (!canCreate) {
558
toggleNotification({
559
type: 'warning',
560
message: 'You do not have permission to create entries'
561
});
562
return;
563
}
564
565
trackUsage('willCreateEntry');
566
lockApp();
567
568
try {
569
await createEntry();
570
trackUsage('didCreateEntry', { status: 'success' });
571
toggleNotification({
572
type: 'success',
573
message: 'Entry created successfully'
574
});
575
} catch (error) {
576
trackUsage('didCreateEntry', { status: 'error', error });
577
toggleNotification({
578
type: 'warning',
579
message: 'Failed to create entry'
580
});
581
} finally {
582
unlockApp();
583
}
584
};
585
586
return (
587
<Button onClick={handleCreateAction}>
588
Create Entry
589
</Button>
590
);
591
};
592
```
593
594
### Provider Setup
595
596
```typescript
597
// Set up multiple feature providers
598
const App = () => {
599
return (
600
<AppInfoProvider {...appInfoProps}>
601
<NotificationsProvider>
602
<TrackingProvider value={trackingConfig}>
603
<OverlayBlockerProvider>
604
<GuidedTourProvider {...tourProps}>
605
<MyApplication />
606
</GuidedTourProvider>
607
</OverlayBlockerProvider>
608
</TrackingProvider>
609
</NotificationsProvider>
610
</AppInfoProvider>
611
);
612
};
613
```
614
615
### Custom Feature Integration
616
617
```typescript
618
// Create custom hook that combines features
619
const useAppFeatures = () => {
620
const appInfo = useAppInfo();
621
const { trackUsage } = useTracking();
622
const toggleNotification = useNotification();
623
624
const reportError = useCallback((error: Error) => {
625
trackUsage('didEncounterError', { error: error.message });
626
toggleNotification({
627
type: 'warning',
628
message: 'An error occurred. Please try again.',
629
timeout: 5000
630
});
631
}, [trackUsage, toggleNotification]);
632
633
return {
634
...appInfo,
635
trackUsage,
636
reportError
637
};
638
};
639
```
640
641
## Context Architecture
642
643
The feature contexts follow a consistent pattern:
644
645
1. **Context Definition**: React context with typed interface
646
2. **Provider Component**: Manages context state and provides value
647
3. **Hook**: Convenient access to context value
648
4. **Type Safety**: Full TypeScript support with proper interfaces
649
650
This architecture ensures:
651
- **Consistent APIs** across all features
652
- **Type Safety** for all context values and operations
653
- **Performance Optimization** through memoized values
654
- **Easy Integration** between different features
655
- **Extensibility** for custom plugin functionality