or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

content-manager.mdfeatures.mdhooks.mdindex.mdtypes.mdui-components.mdutilities.md

features.mddocs/

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