@graphicacy/copy
v0.1.9
Published
Zero-config content layer for React, SvelteKit, and Next.js. Wrap text in <Copy>, get a structured strings file at build time.
Readme
@graphicacy/copy
A zero-config content layer for React, SvelteKit, and Next.js. Wrap text in a
<Copy> component; a build-time plugin extracts it to YAML; editor overrides
get inlined back into your bundle at build time. No runtime API, no provider,
no editor account required during development.
Installation
npm install @graphicacy/copyPre-1.0 — treat minor version bumps (0.X.0) as potentially breaking, patch
bumps (0.0.X) as additive only. Pin to a caret range like ^0.1.0 for
predictable upgrades.
Quick usage
React + Vite
// vite.config.ts
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import { copy } from '@graphicacy/copy/vite';
export default defineConfig({
plugins: [react(), copy()],
});import { Copy } from '@graphicacy/copy/react';
export function App() {
return (
<main>
<h1><Copy>Welcome to Acme</Copy></h1>
<p><Copy>The platform for modern data visualization.</Copy></p>
</main>
);
}SvelteKit
// vite.config.ts
import { defineConfig } from 'vite';
import { sveltekit } from '@sveltejs/kit/vite';
import { copy } from '@graphicacy/copy/vite';
export default defineConfig({
plugins: [copy(), sveltekit()], // copy() MUST come first
});<script>
import { Copy } from '@graphicacy/copy/svelte';
</script>
<h1><Copy>Welcome to Acme</Copy></h1>Next.js (App Router)
// next.config.ts
import { withCopy } from '@graphicacy/copy/next';
export default withCopy({});import { Copy } from '@graphicacy/copy/react';
export default function Page() {
return <h1><Copy>Welcome to Acme</Copy></h1>;
}No 'use client' boundary required on your pages — the server renders the
initial HTML and overrides are inlined at build time.
How it works
After your first build, .cms/strings.generated.yaml is written. The file
maps each <Copy> occurrence to its default content with a stable ID.
version: 1
entries:
- primaryId: a3f2c1
secondaryId: src/App.tsx:0
default: Welcome to Acme
current: Welcome to Acme # edit this to override; build inlines it
mode: plainCommit the generated YAML to git — it's the contract between source code and
edited content. To change what ships in the bundle, edit the current: field
of an entry; the next build inlines it. Zero runtime cost: <Copy> is a thin
shell with no provider, no lookup, no override map on the wire.
Syncing edits back to source
When current differs from default (an edit was made in the YAML or via the
editor), you can fold those edits back into your source <Copy> blocks so
git diff reflects them and the source stays the single source of truth:
npx graphicacy-copy syncThis rewrites the matching <Copy> defaults in source and resets
default = current in the YAML. It's an explicit step — starting the dev
server does not mutate your source files. Run it after pulling editor
edits, then review the diff and commit.
Preview first with --dry-run — it lists the source files that would change
without writing anything:
npx graphicacy-copy sync --dry-runOther options: --strings <path> (YAML location, default
.cms/strings.generated.yaml), and --rich-tags / --block-tags if you've
customized the allowed-tag lists in your plugin config. Run
npx graphicacy-copy sync --help for details.
Prefer the old behavior of syncing automatically on dev start? Pass
syncOnDevStart: trueto the plugin (copy({ syncOnDevStart: true })/withCopy(nextConfig, { syncOnDevStart: true })).
Edit mode
An opt-in browser overlay lets authors edit <Copy> text in-place on a
running preview deployment. Contact your Graphicacy integration team for setup.
License
MIT
