Skip to content

Latest commit

Β 

History

History
290 lines (225 loc) Β· 11.1 KB

File metadata and controls

290 lines (225 loc) Β· 11.1 KB

@fecommunity/reactpress-toolkit

Official TypeScript SDK for the ReactPress publishing platform.

npm version npm latest npm downloads License: MIT

The shared foundation for ReactPress themes, plugins, Admin extensions, and custom frontends. Auto-generated OpenAPI clients, Next.js theme SSR helpers, plugin admin hooks, and headless React UI β€” so you extend the platform instead of duplicating API or rendering logic.

Use case Start here
Next.js themes ./theme, ./theme/next-config, ./app
Plugins ./plugin, ./plugin/admin, ./plugin/client
API integration ./api, ./api/instance, ./types
Headless UI ./ui β€” unstyled components and hooks

Documentation Β· ReactPress CLI Β· GitHub

Package exports (package.json β†’ exports)

Subpath Purpose
. Root entry: api, config, theme, ui, plugin namespaces and common re-exports
./api HTTP client classes per resource
./api/instance Default api instance and createApiInstance
./types Swagger-generated request/response types
./utils Framework-agnostic utilities (see module table below)
./config Env vars, global defaults, i18n strings (config/locales/*.json)
./theme Visitor themes: SSR data fetch, runtime, extension config types; re-exports ./ui
./theme/next-config createReactPressNextConfig()
./theme/node Node-only helpers (e.g. read theme admin locale files)
./ui Unstyled theme components and hooks
./plugin Admin plugin aggregate entry
./plugin/admin Menu registration, permission constants
./plugin/client Web/Electron API client factory (recommended)
./plugin/react Same as ./plugin/client (legacy path)
./plugin/dev Vite dev port redirect, etc.

Convention: Only top-level directories under src/ match the exports above; implementation details live in subdirectories with thin shims at the root (e.g. theme/node.ts β†’ theme/build/node.ts).

Source layout

src/
β”œβ”€β”€ api/              # OpenAPI generated (do not hand-edit business logic)
β”œβ”€β”€ config/           # env, global, i18n + locales/
β”œβ”€β”€ types/            # Swagger generated types
β”œβ”€β”€ utils/            # Pure utilities (shared by theme/plugin)
β”‚   β”œβ”€β”€ api-envelope.ts   # unpackList / unpackOne / unpackPaginated
β”‚   β”œβ”€β”€ cookie.ts         # readRequestCookie
β”‚   β”œβ”€β”€ date.ts           # formatDate, formatPublishDate*
β”‚   β”œβ”€β”€ email.ts          # Comment email validation
β”‚   β”œβ”€β”€ error.ts          # ApiError, isApiError
β”‚   β”œβ”€β”€ json.ts           # safeJsonParse
β”‚   β”œβ”€β”€ jsonp.ts          # Browser JSONP
β”‚   β”œβ”€β”€ object.ts         # deepMerge, getByPath, deepClone
β”‚   β”œβ”€β”€ setting.ts        # pickSiteSettings
β”‚   └── string.ts         # stripHtml, truncateWords
β”œβ”€β”€ plugin/
β”‚   β”œβ”€β”€ admin/        # AdminModule, menu registration, permissions
β”‚   β”œβ”€β”€ client/       # createClient, resolveApiBaseUrl
β”‚   β”œβ”€β”€ dev/          # devPortRedirectPlugin, etc.
β”‚   └── react/        # Re-export client only (compat)
β”œβ”€β”€ theme/
β”‚   β”œβ”€β”€ api/          # themeApi, axios wrapper
β”‚   β”œβ”€β”€ ssr/          # fetch, static props, site meta
β”‚   β”œβ”€β”€ visitor/      # Language, session, colors, runtime mods
β”‚   β”œβ”€β”€ content/      # SEO, nav paths, excerpts, static asset URLs
β”‚   β”œβ”€β”€ preview/      # Preview token / mods / config query params
β”‚   β”œβ”€β”€ createCatalogApp.js  # Full theme _app factory (no UI framework)
β”‚   β”œβ”€β”€ createApp.js  # Next `_app` factory (allowJs, emitted to dist)
β”‚   β”œβ”€β”€ extension/    # theme.json schema, site config, shared server types
β”‚   β”œβ”€β”€ node.ts       # β†’ build/node
β”‚   β”œβ”€β”€ next-config.ts
β”‚   └── index.ts      # Public barrel
└── ui/
    β”œβ”€β”€ components/   # Unstyled React components
    β”œβ”€β”€ context/      # ReactPressProvider, locale, runtime
    └── hooks/        # Generic React hooks

Install

pnpm add @fecommunity/reactpress-toolkit

Quick start

API client

import { api } from '@fecommunity/reactpress-toolkit';
// or
import { api, createApiInstance } from '@fecommunity/reactpress-toolkit/api/instance';

const articles = await api.article.findAll();

Custom baseURL:

import { createApiInstance } from '@fecommunity/reactpress-toolkit/api/instance';

const customApi = createApiInstance({ baseURL: 'https://api.example.com/api' });

Utilities (./utils)

Framework-agnostic logic belongs in utils; theme re-exports for @fecommunity/reactpress-toolkit/theme compatibility:

import {
  safeJsonParse,
  unpackList,
  formatPublishDate,
  stripHtml,
  deepMerge,
  getByPath,
  pickSiteSettings,
} from '@fecommunity/reactpress-toolkit/utils';
Module Typical use
json Parse JSON strings in settings
api-envelope Unwrap Nest TransformInterceptor { data }
date Article publish date display
string Strip HTML for archive excerpts, truncate
object Merge theme.json config, dot-path read/write
setting Map settings rows to props
cookie Read Cookie header in SSR
email Visitor comment email format

Admin plugins

import type { AdminModule } from '@fecommunity/reactpress-toolkit/plugin/admin';
import { permissionsForRole } from '@fecommunity/reactpress-toolkit/plugin/admin';

Web / Electron client

import { createClient, resolveApiBaseUrl } from '@fecommunity/reactpress-toolkit/plugin/client';

App factories (./app)

Entry factories for theme _app.tsx, UI-framework agnostic:

Factory Purpose
createThemeApp Minimal theme (hello-world): ReactPressProvider + ThemeCssVars
createReactPressApp Full theme: SSR catalog, i18n, analytics, PV; inject Ant Design etc. via wrapContent
import { createThemeApp } from '@fecommunity/reactpress-toolkit/app';
import { createReactPressApp } from '@fecommunity/reactpress-toolkit/app';

Also re-exported from ./theme (legacy paths).

Theme development (./theme)

Next.js visitor themes should use toolkit API and SSR helpers instead of copying lib/api.ts per theme.

import {
  themeApi,
  fetchVisitorContext,
  fetchThemeCatalog,
  themeStaticProps,
  unpackList,
} from '@fecommunity/reactpress-toolkit/theme';
import { createThemeApp } from '@fecommunity/reactpress-toolkit/app';
// next.config.js
const { createReactPressNextConfig } = require('@fecommunity/reactpress-toolkit/theme/next-config');
module.exports = createReactPressNextConfig();
// pages/_app.tsx
import themeManifest from '../theme.json';

export default createThemeApp(themeManifest);

Full-featured themes β€” use createReactPressApp (UI-framework agnostic); keep Ant Design and heavy deps in the theme:

import { createReactPressApp } from '@fecommunity/reactpress-toolkit/app';
import { ConfigProvider } from 'antd';
import { NextIntlProvider } from 'next-intl';

export default createReactPressApp(themeManifest, {
  Layout: AppLayout,
  IntlProvider: NextIntlProvider,
  wrapContent: (content, { locale, isDark, colorPrimary }) => (
    <ConfigProvider locale={{ locale }} theme={{ token: { colorPrimary } }}>
      {content}
    </ConfigProvider>
  ),
});

createReactPressApp includes: SSR site data, preview mods, SiteCatalogProvider, route progress, analytics scripts, PV reporting. Does not include Ant Design / cssinjs.

REST providers β€” avoid copying 14 provider files per theme:

import { createThemeAxiosClient, createThemeProviders } from '@fecommunity/reactpress-toolkit/theme';

export const httpProvider = createThemeAxiosClient({ onError, onUnauthorized });
export const { ArticleProvider, CategoryProvider, TagProvider } = createThemeProviders(httpProvider);

Env: REACTPRESS_API_URL (SSR), NEXT_PUBLIC_REACTPRESS_API_URL (browser), injected by reactpress theme dev.

Headless UI (./ui)

Also importable from ./theme:

import { NavMenu, ArticleList, ReactPressProvider, useLocale } from '@fecommunity/reactpress-toolkit/ui';
Symbol Description
ReactPressProvider Inject site context in _app
useLocale / useThemeRuntime / useThemeMod Language and theme mods
useToggle / useAsyncLoading Boolean toggle, debounced loading
usePagination [items, total] paginated lists
useReportArticleView / useReportPageView Article views, site PV
useRouteParam / useNavActive Dynamic route params, nav highlight
useWarningOnExit Confirm before leaving page (Next Router)
NavMenu Config-driven nav via renderLink + Next Link
ArticleList List renderer via renderArticle
SiteCatalogProvider / useSiteSetting / useSiteUser Site catalog + user session
SiteSeo / RouteProgress / SiteAnalytics SEO meta, progress bar, GA/Baidu
ArticleReader / HtmlContent / ArticleToc Article reading, HTML, TOC
ImageViewer / LocaleTime Image preview, localized time
createReactPressApp Full theme _app factory
fetchAppBootstrap _app.getInitialProps SSR data

Extension config types

Types and validation in theme/extension are shared with server and web appearance settings, e.g. ThemeConfigurationSchema, resolveSiteConfig, PUBLIC_SETTING_KEYS. Server example:

import { PUBLIC_SETTING_KEYS, systemGlobalSettingDefaults } from '@fecommunity/reactpress-toolkit/theme';
import { readThemeAdminLocaleFile } from '@fecommunity/reactpress-toolkit/theme/node';

Regenerate API from Swagger

From monorepo root, ensure server builds:

cd toolkit && pnpm run generate

Updates src/api/* and src/types/*.

Build

cd toolkit && pnpm run build

Output in dist/; createApp.js is emitted via tsc (allowJs) to dist/theme/createApp.js.

Scripts

Command Description
pnpm run generate Generate API from server Swagger
pnpm run build tsc + copy locales
pnpm run typecheck Type check only

License

MIT Β© FECommunity

Part of ReactPress β€” the official SDK for themes, plugins, and custom frontends.