A React-only newsletter UI. There is no backend, API layer, or server-rendered app in this project. Newsletter content lives inside the React app, so most future releases should only need changes in one file:
src/app/content/newsletter.ts
- React for the UI
- Parcel for local dev and production bundling
- TypeScript for type safety
- Tailwind CSS for styling
Everything runs in the browser. The project does not require a separate backend service.
npm install
npm run devOpen the local URL Parcel prints, usually http://127.0.0.1:5173.
- Open
src/app/content/newsletter.ts. - Update the top-level
preparedByvalue if needed. - Keep or update the top-level
logo. - Edit, add, remove, or reorder items in
newsletter.pages. - For each page, update:
brandeditionLabelherocolumns.leftcolumns.rightsections
- Run
npm run check.
You do not need to create a new React component or another app layer for the next newsletter. Add another object to newsletter.pages, or update the existing page objects.
Each page can use these section types:
{ type: 'image', image: { src, alt } }
{ type: 'cards', cards: [...] }
{ type: 'stats', title, items: [...] }
{ type: 'comparison', title, tone, items: [...] }
{ type: 'steps', title, lead, tone, steps: [...] }
{ type: 'metrics', title, tone, items: [...] }Use columns.left and columns.right for the main two-column story area. Use sections for full-width content after the columns.
Steps can include an optional short label such as Scope, Build, or Launch. The label appears above the step title in the rollout timeline.
For local images, put the file inside src and import it in src/app/content/newsletter.ts:
import reportImage from '../assets/poc.jpeg';Then use it in a section:
{
type: 'image',
image: {
src: reportImage,
alt: 'Short description for accessibility',
},
}Remote image URLs also work, but local images are better when the React app must keep working offline or in a private environment.
Available tones:
indigo, blue, emerald, amber, purple, red, cyan, slate
Available icons:
sparkles, target, clock, lightbulb, check, none
Header gradients are Tailwind classes, for example:
bg-[linear-gradient(120deg,#0b0d0e_0%,#053057_62%,#031114_100%)]
src/main.tsxboots the React appsrc/app/App.tsxhandles the screen view and print viewsrc/app/content/newsletter.tsis the in-app content sourcesrc/app/components/newsletter/*contains the reusable newsletter UI
If the project stays UI-only, you do not need to add Express, Next.js, a database, or an API server.
npm run typecheck
npm run build
npm run checknpm run check runs TypeScript and the production build. TypeScript is configured to fail on unused locals and unused parameters, so dead imports are caught early.
npm run build
npm run previewOpen http://127.0.0.1:4173.
Use print preview in one of these ways:
/print
?view=print
When the app is hosted as plain static files, ?view=print is the safest option because it does not need server rewrites. On this page you can choose paper size from A1 to A6. Each newsletter page is locked to a single physical page for cleaner PDF export and email sharing.
For best results:
- Open
?view=print(or/printwhen your host supports rewrites). - Select paper size in the toolbar.
- Click
Print / Save PDF. - In the browser print dialog, keep
Background graphicsenabled.
Browser shows old UI
Hard refresh with Cmd+Shift+R, then restart the dev server if needed.
localhost is not working
Use 127.0.0.1. Some environments fail DNS resolution for localhost.
Port already in use
Parcel may choose another port if 5173 is busy.
An image does not show
Check that the import path is relative, not machine-specific. Avoid paths like /Users/name/project/....