Skip to content

fecommunity/reactpress-plugin-starter

Repository files navigation

ReactPress Plugin Starter

Starter template for building ReactPress plugins — server-side hooks, manifest-driven settings, locales, and Admin UI slots.

Aligned with fecommunity/reactpress/plugins · Plugin system reference · 简体中文

Overview

ReactPress plugins extend server-side business logic (hooks, content rules, integrations). They follow a WordPress-style model: install and enable from Admin, configure via plugin.json, integrate through register() and hook subscriptions.

Extension Responsibility Runtime
Theme Visitor UI, SSR Next.js (:3001)
Plugin Business rules, hooks NestJS API (:3002)
Webhook Outbound async notifications Server HTTP

Boundary: plugins must not inject theme routes or modify the Next.js build. Themes must not write to the database directly.

This repository ships a minimal working plugin (plugin-starter) that demonstrates:

Capability Implementation
Server entry src/server/index.tsregister(hooks, ctx)
Hook subscription article.afterPublish (action)
Manifest plugin.json with settings.schema
Admin settings page admin.menu/plugins/plugin-starter/settings
i18n src/locales/{locale}.json
Admin slot src/admin/ + admin.slotsarticle.editor.meta.afterSummary

Requirements

Item Version
Node.js >= 18
ReactPress >= 4.0.0 (see plugin.jsonrequires)
Toolkit @fecommunity/reactpress-toolkit@^4.0.0-beta.18 (types & server build)

Targets the ReactPress 4.0 plugin layout (src/server, src/admin, src/locales). Install into the ReactPress monorepo for full runtime. The plugin/server subpath is exported from toolkit 4.x beta only.

Quick start

1. Install dependencies

git clone <your-repo-url> my-plugin
cd my-plugin
npm install   # .npmrc enables legacy-peer-deps for toolkit peer resolution

2. Customize the plugin

File Purpose
plugin.json id, name, version, server.hooks.subscribe, settings.schema
package.json Package name (e.g. @your-scope/reactpress-plugin-my-plugin)
src/server/index.ts Hook handlers and business logic
src/locales/*.json Admin UI strings for plugin name and settings fields

Plugin id rules: kebab-case; must match the directory name under plugins/{id}/ in your ReactPress project.

3. Build

npm run build
# Output: dist/index.js  ← referenced by plugin.json → server.module

4. Register in a ReactPress project

Copy or symlink this directory into the ReactPress monorepo as plugins/{id}/ (id must match plugin.jsonid):

# From your ReactPress project root
cp -r /path/to/my-plugin plugins/my-plugin

Update plugin.json$schema to the monorepo-relative path:

"$schema": "../plugin.manifest.schema.json"

Add the plugin id to plugins/package.json:

{
  "reactpress": {
    "local": ["my-plugin"]
  }
}

Start development:

pnpm dev   # compiles local plugins before the API starts

Enable the plugin:

  • Admin: Plugins → Install → Enable → Settings
  • CLI: reactpress plugin install my-plugin && reactpress plugin activate my-plugin

Plugin enable/disable does not require an API restart — hooks are hot-loaded at runtime.

Directory structure

Every plugin package uses the same layout: manifest at the root, all TypeScript under src/, split by runtime (aligned with ReactPress 4.0):

plugin-starter/
├── plugin.json                 # Manifest (id, hooks, settings schema, admin slots)
├── plugin.manifest.schema.json
├── package.json
├── tsconfig.json               # extends tsconfig.base.json — server compile only
├── tsconfig.base.json          # shared tsc defaults
├── README.md
├── README_zh.md
├── src/
│   ├── server/                 # Node hook logic → tsc → dist/
│   │   ├── index.ts            # export register(hooks, ctx)
│   │   ├── config.ts
│   │   └── types.ts
│   ├── admin/                  # React Admin UI (bundled by web via Vite)
│   │   ├── index.ts            # export registerAdmin(registry, ctx)
│   │   └── StarterPanel.tsx
│   └── locales/                # Admin UI strings (en.json, zh.json, …)
│       ├── en.json
│       └── zh.json
└── dist/                       # plugin.json → server.module (./dist/index.js)
    └── index.js
Path Runtime Build
src/server/ NestJS require() at API startup npm run buildtscdist/
src/admin/ Admin SPA (Vite import.meta.glob) Compiled when building web/
src/locales/ Admin i18n API No build — served as JSON
plugin.json Install / enable / config No build

Hook system

This starter subscribes to one hook:

Hook Type Behavior in this template
article.afterPublish action Logs article title to server output when logTitle is enabled

Built-in hooks (full list in the plugin system reference):

Hook Type
article.beforeCreate filter
article.beforePublish filter
article.afterPublish action
comment.beforeCreate filter
comment.afterCreate action

Server entry contract

This template implements article.afterPublish:

import type { HookService, PluginContext } from '@fecommunity/reactpress-toolkit/plugin/server';

export function register(hooks: HookService, ctx: PluginContext): void {
  hooks.addAction(
    'article.afterPublish',
    async (payload) => {
      // handle { article, isNew }
    },
    { priority: 10, pluginId: ctx.id },
  );
}

export function deactivate(): void {} // optional: cleanup on disable

Configuration

Settings are declared in plugin.jsonsettings.schema and persisted at:

globalSetting.plugins.entries.{id}.config

Update via Admin Settings or REST API:

curl -X PUT http://localhost:3002/api/extension/plugins/plugin-starter/config \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{"config":{"enabled":true,"logTitle":false}}'

Saving config triggers an automatic plugin reload.

Admin UI

plugin.json declares both a settings menu (admin.menu) and an editor slot (admin.slots). When the plugin is active, ReactPress Admin loads src/admin/index.ts via Vite import.meta.glob and calls registerAdmin().

Declaration Purpose
admin.menu WordPress-style settings page at /plugins/{id}/settings
admin.slots.subscribe Built-in editor mount points (enum ids)
src/admin/index.ts registerAdmin() — register slot components

Plugins with only admin.menu (no src/admin/) still get a settings page — see hello-world.

Built-in slot ids:

Slot id Location
article.editor.meta.afterSummary Article editor — below summary
article.editor.sidebar.afterPublish Article editor — below publish box

Development

Command Purpose
npm run build Compile src/server/dist/
npm run typecheck Type-check without emit
npm run clean Remove dist/

After editing src/server/, rebuild and deactivate → reactivate the plugin in Admin, or save config to trigger reload. After editing src/admin/, rebuild the ReactPress web/ package.

Dependency boundaries

Import path Used in Purpose
@fecommunity/reactpress-toolkit/plugin/server src/server/ HookService, PluginContext
@fecommunity/reactpress-toolkit/plugin/admin src/admin/ Slot registration
@fecommunity/reactpress-toolkit/plugin/react Core Admin pages <AdminSlot /> mount points

Rule: src/server/ must only import from @fecommunity/reactpress-toolkit/plugin/server.

Forking this template

Reference implementations: hello-world (server + settings menu), seo (server + admin slots).

  1. Copy this repository to plugins/{your-id}/
  2. Update plugin.jsonid, name, server.hooks.subscribe
  3. Implement business logic in src/server/
  4. Register the id in plugins/package.jsonreactpress.local

Related resources

Resource Link
ReactPress documentation docs.gaoredu.com
ReactPress source github.com/fecommunity/reactpress
Plugin system reference plugins/README.md
Built-in plugin example plugins/hello-world
Theme starter reactpress-theme-starter
Toolkit (npm) @fecommunity/reactpress-toolkit

MIT License · © ReactPress / FECommunity

About

Starter template for building ReactPress plugins — server-side hooks, manifest-driven settings, locales, and Admin UI slots.

Topics

Resources

License

Stars

1 star

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors