Content library
A reusable store of post templates, snippets, and hashtag bundles for the composer — working today against browser storage, with server-side sync as the planned next step.
Content library
The content library is where a workspace keeps the copy it reuses: full post
templates, short snippets, and hashtag bundles you drop into the
composer instead of retyping. Each item carries a name, body, tags, and a
popularity signal — a use_count and last_used_at that bump every time you
click "Use," so your most-reached-for content floats to the top of the rail.
Backend storage is not shipped yet — this is browser-local
The library currently persists to localStorage, not to a Pact server table
(web/src/app/(app)/social/library/library-store.ts; the gap is tracked in
docs/design/pact-social-channel-gaps.md §5). Consequences to know:
- Items live in one browser on one device. They do not sync across devices, teammates, or a re-install, and clearing site data erases them.
- Keys are tenant-scoped, so switching workspaces in the same browser won't bleed templates across tenants — but there is no server-side isolation because there is no server-side store yet.
When the backend API lands, this module is swapped for an API client and a
one-time migration copies existing localStorage items up to the server on
first authenticated load.
What's in the library
| Kind | Use |
|---|---|
template | A full post you reuse and lightly edit — announcements, weekly formats, event promos. |
snippet | A reusable fragment — a CTA line, a disclaimer, a signature block. |
hashtag_bundle | A named set of hashtags you append in one click. |
Items surface popularity through use_count and last_used_at, so the rail can
rank by what the team actually reaches for.
Roadmap
Planned: server-backed, team-shared library
The intended end state is a shared, tenant-isolated library stored server-side so every teammate sees the same templates, edits sync, and popularity is aggregated across the workspace rather than per-browser. Until that ships, treat the library as a convenient per-browser scratch store — anything you can't afford to lose should also live in the composer as a saved draft or in your own document store.