@silo-software/react
v0.4.2
Published
React hooks and components for Silo sites
Readme
@silo-software/react
React hooks and components for Silo sites: reader session, favorites, newsletter, article access, search, analytics and the optional PDF issue reader. Builds on @silo-software/sdk. Use an HttpOnly-cookie BFF for production reader credentials.
Optional PDF issue reader
@silo-software/react/reader exports CmsIssueReader, the extracted
CmsPdfViewer, and useCmsPinnedIssuePosition. This optional entry needs host
React/React DOM19 and react-pdf 10.4.1. Its installed renderer depends on
PDF.js 5.4.296; no direct files/parser dependency is changed. The existing
@silo-software/react, delivery/client/DTO and @silo-software/sdk/server exports keep their existing purpose.
Import @silo-software/react/reader.css from the host's layout. The package
build copies this stylesheet into dist; it imports React-PDF's matching
text/annotation styles. No Tailwind, internal design system, dictionary provider,
DB, tRPC or monorepo path aliases are required by the reader entry.
import { CmsIssueReader } from '@silo-software/react/reader';
// Host supplies a full, approved release pin and localized CmsReaderCopy.
<CmsIssueReader pin={pin} title={title} closeHref={issueHref} copy={copy}
authorizationUrl={sameOriginDescriptorUrl} readerUrl={sameOriginPinnedPdfUrl} />The descriptor must freshly authorize the same tenant/site/ReaderSession through
the canonical CMS policy and return publicationId, pdf with all five pin keys,
and positionScope: string | null. positionScope is a server-derived SHA-256
partition of the actual session reader plus tenant/integration identity; it is
never a bearer token. Null means no position persistence. The Starter derives
it in its existing BFF, using the same optional ReaderSession operation and
refresh path as the issue descriptor; raw reader identity is not sent to storage.
The PDF URL must contain exactly the approved assetId/versionId/runId/
manifestDigest/sectionDigest. Keep the current authenticated range-capable,
no-store PDF proxy. Metadata or localStorage never grants byte access.
Initial authorization gates mounting. The exact pin and actor partition must stay unchanged throughout that mounted reader. Focus/visible/30s background checks preserve the current document while pending; current denial/failure or pin/session change closes it. Per-request supersession guards apply through async search reads, one-time position restore and localStorage writes. Reopening is an explicit new authorization operation. Position is a page hint on this device only, reauthorized before restore/write; no token/text/cross-device state is stored. Anonymous readers have no persisted hint.
The extracted viewer keeps existing fit/zoom50–200, desktop spreads/mobile single
pages, bounded visible page rendering and observed page events. It adds a real
PDF outline (getOutline through React-PDF Outline) and main text/annotation
layers. PDFs without outline/text show an empty state; there is no fabricated
TOC or OCR. Search is cancellable, limited to2000 pages/query200 characters and
100 result pages. Text stays in memory and is cleared when access/document ends.
Search snippets navigate to pages; exact hit boxes/region authoring remain R3.
Local assets: provide /api/pdfjs/[assetType]/[fileName] with
@silo-software/next/pdfjs getCmsPdfJsAssetResponse({ ...params, appPackageJson }), using the HOST
app's absolute package.json path. It resolves PDF.js from that host's installed
react-pdf/package.json, verifies the version embedded in assetType, and serves
only renderer worker/cmaps/fonts/wasm resources. No CDN is used. URLs are
/api/pdfjs/react-pdf-5.4.296-worker/pdf.worker.min.mjs and the corresponding
-cmaps/, -standard_fonts/, -wasm/ directories. Versioned immutable asset
URLs never carry document bytes. The only worker filename allowed is
pdf.worker.min.mjs; safe filename/type guards remain enforced.
For Next standalone deployment use getCmsPdfJsTraceIncludes(appPackageJson)
for the asset route's outputFileTracingIncludes. It explicitly includes host
package metadata, renderer metadata/dependency boundary, matching worker and
asset trees. The Starter's build stages static/public files beside the standalone
server; its independent export rewrites start to
node .next/standalone/server.js. Preserve the generated node_modules/link layout
and launch from the generated server directory (the Next server changes cwd).
The export script builds/packs this SDK into vendor, replaces workspace dependency
with the tarball and retains ordinary pinned renderer dependencies. No monorepo
client bundle is assumed to supply the worker or server package resolver.
This is a source draft. No installation, compiler/build, tarball export, browser, native PDF, tracing or deployment run has validated it. In particular, actual standalone resolver links/cwd/static paths and independently installed dependencies must be exercised before accepting portability. R3 article/ad regions, authoring and precise rotation/CropBox/highlight geometry remain required.
The PDF entry is browser-only: the Next Starter loads it with next/dynamic and
ssr:false inside its existing client component. Do not evaluate the PDF renderer
during server rendering. For hosts that need the position hook before loading
the PDF UI, use the separate pure React entry
@silo-software/react/reader-position; it has no PDF renderer runtime import.
The internal adoption delta likewise loads CmsPdfViewer only on the client.
Analytics
Wrap the site in SiloAnalyticsProvider with a same-origin collector endpoint and the reader's consent. Use useSiloAnalytics() to send events and useArticleAnalytics({ articleId, contentRef?, readingTimeSeconds? }) to track an article. The provider updates consent and cleans up on unmount.
For sites that supply tenant and site context directly, useAnalyticsTracker(context, { endpoint, consent, isInitialized, consentSource }) uses the same event builder and queue. Pair it with usePageEngagementTracker for engagement and scroll, and useAnonymousUser for consent-enabled identity.
@silo-software/react/knowledge-base provides release adapters and the public Markdown renderer for Silo knowledge bases.
Content rendering
@silo-software/react/content exports the Silo article renderer, content HTML hydration, media gallery, quote and social embed components. Articles with app blocks render through ArticleAppContent, fed by resolveAppContent from @silo-software/sdk/content (server side, with the site's server secret). Include dist in your Tailwind sources when using these components.
Reader session hooks are available from @silo-software/react/reader-session.
