Skip to content
glennfaisonPublic

About

Simple page builder

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

291 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

LivePage

LivePage is a visual page builder. You compose a page from design components in an in-browser editor, connect components to data sources, and export the result as JSON, shortcode, or a standalone HTML file.

Status: early development (0.1.0). Formats and APIs can change without notice.

Features

  • Visual editor. Add, replace, and configure design components such as headers, rows, columns, images, stats, callouts, charts, metric cards, and data tables. Includes undo/redo history and a command palette.
  • Data sources. Bind components to REST APIs, GraphQL, JSON feeds, RSS feeds, CSV, generated data, or an authorized LinkedIn OIDC profile through placeholders.
  • Templates. Start from bundled templates: SaaS landing page, agency homepage, personal portfolio, CV/resume, blog article, event page, link-in-bio, contact/about, and patient health dashboard.
  • Page assistant (optional). Describe the page you want in plain language; a chat picks a template, drafts its text, and tunes its design settings. Off unless enabled with NEXT_PUBLIC_PROMPT_ASSIST_ENABLED=1. Once enabled, toggle it on in the Settings popover (toolbar) to show the chat bubble (bottom-right) without needing a URL parameter. Includes a command palette action ("Open AI Assistant"), first-visit tooltip, and in-app help; see Optional: page assistant.
  • Import and export. Save and load pages as JSON or shortcode, or export a standalone HTML page.

Getting started

You need Node.js 18.18 or newer and npm.

npm install
npm run dev

Open http://localhost:3000 for the landing page, or go straight to the builder at http://localhost:3000/try.

Optional: page assistant

The feature is off by default. Set NEXT_PUBLIC_PROMPT_ASSIST_ENABLED=1 and rebuild (the value is inlined at build time) to turn it on. Once enabled, the chat bubble (bottom-right of /try) can be shown in two ways:

  1. Per-visit URL parameter: Open the builder with ?prompt-assist=1 (e.g., /try?prompt-assist=1).
  2. Persistent setting: Toggle "Enable AI Assistant" in the Settings popover (toolbar gear icon). This persists across visits in localStorage and does not require the URL parameter.

With the deployment flag off, the /api/prompt-assist routes answer 404. It uses TypeSafe's Jev and/or OpenAI. Copy .env.example to .env.local and set TYPESAFE_API_KEY and/or OPENAI_API_KEY; with neither, the chat lets you pick a template by hand and everything else works as before. Keys stay on the server, and the request text is sent to whichever provider you configure. How it works is described in .agents/docs/CONTEXT.md.

Discoverability features:

  • Toolbar toggle: Enable/disable the AI Assistant from the Settings popover.
  • Command palette: Press ⌘K and search "Open AI Assistant" to open the chat.
  • First-visit tooltip: A helpful tooltip appears on first visit explaining the feature.
  • In-app help: The Settings popover includes a description of the AI Assistant.

Optional: LinkedIn profile data source

The LinkedIn Profile source uses LinkedIn's official OpenID Connect authorization code flow. In your LinkedIn developer app, enable the Sign In with LinkedIn using OpenID Connect product and authorize the openid, profile, and email scopes. Register the exact value of LINKEDIN_REDIRECT_URI as an authorized redirect URL. For local development, use http://localhost:3000/api/linkedin-profile/callback; production must use the HTTPS callback URL for your deployment. The integration uses LinkedIn's OIDC discovery document and the userinfo endpoint.

Set LINKEDIN_CLIENT_ID, LINKEDIN_CLIENT_SECRET, LINKEDIN_REDIRECT_URI, and LINKEDIN_SESSION_ENCRYPTION_KEY in .env.local using the names in .env.example. Generate the encryption key with openssl rand -base64 32. The client secret stays on the server. The profile session is stored in an encrypted, HttpOnly, SameSite=Lax cookie; it is protected from client-side JS read access and expires after eight hours, but it is not cryptographically bound to one browser/device. It requires HTTPS in production and is removed on disconnect. LinkedIn data is loaded only through the same-origin profile endpoint and is not stored in source settings, app nodes, or exports.

Available profile values are limited to claims returned by the configured app's LinkedIn OIDC scopes: subject, name, given/family names, picture, locale, and the optional email and email-verification claim. LinkedIn does not expose headline, about/summary, positions, education, or skills through this normal self-serve OIDC profile. Those template fields remain empty; access to broader profile permissions requires LinkedIn approval. LivePage does not scrape LinkedIn. Standalone HTML files cannot use the LinkedIn session cookie.

Development

Command What it does
npm run dev Start the development server
npm run build Create a production build
npm start Serve the production build
npm run lint Run ESLint through next lint
npm test Run the Jest suite
npm run test:watch Run Jest in watch mode
npm run test:coverage Run Jest with coverage
npm run build:html-runtime Rebuild the browser runtime used by HTML exports
npm run test:html-browser Run the standalone HTML artifact regression test in Chromium
npm run check:branch Check that the current branch name follows gitflow
npm run verify Lint + full Jest suite (--runInBand) + branch-name check (convenient pre-PR gate)

The dev, build, start, and test commands rebuild the HTML export runtime automatically. It is generated into client/features/serializers/html/generated/, which is git-ignored.

The standalone HTML browser tests run in headless Chromium against both the live /try?template=<id>&mode=preview page and the exact exported HTML for every bundled template at desktop and mobile viewport sizes. They fulfill pinned React imports from locally installed React packages and use the preview's local font assets, so the comparison does not depend on CDN availability. To install the browser locally, run npx playwright install chromium once after npm install; then run npm run test:html-browser.

The app is built with Next.js (App Router), React 19, TypeScript, Tailwind CSS, Radix UI, and Zod. Tests use Jest and Testing Library.

Branch names

Pushes must use a gitflow branch name, or a dependabot/<dependency> branch for automated dependency updates. The check applies to people, agents, and other automation. Topic segments are lowercase kebab-case.

Branch type Pattern Example
main main main
develop develop develop
dependabot dependabot/<dependency> dependabot/dependencies/node/22
feature feature/<topic> feature/login-flow
release release/<version> release/1.4.0
hotfix hotfix/<topic> hotfix/crash-on-start
support support/<version-line> support/1.x
bugfix bugfix/<topic> bugfix/null-deref

A rejected name lists these patterns. CI runs node scripts/check-branch-name.mjs on every push and pull request. git config core.hooksPath scripts/git-hooks enables a local pre-push gate that refuses non-compliant branches. The server-side GitHub ruleset is the check that cannot be skipped; see .agents/docs/BRANCH-NAMES.md.

Project layout

Application code is organized by runtime: browser features and UI live in client/, backend features and integrations in server/, and runtime-neutral models and contracts in shared/. Each runtime groups domain code in its own features/ subfolder. The Next.js route tree stays in app/; page files import client features, while API route files are thin adapters to server features. UI primitives live in client/components/ui/. .agents/docs/CONTEXT.md has the module map and import-boundary rule.

HTML exports

An HTML export is a single file that opens directly in a modern browser, with no LivePage server needed. It bundles the same registered preview-component implementations and compiled Tailwind CSS generated from the builder's global stylesheet. Keep these limits in mind:

  • The file loads pinned React and ReactDOM builds from esm.sh, and Inter from Google Fonts, so the browser needs network access when it opens the file.
  • The export runtime uses the registered preview data-source implementations. Network-backed sources must allow the exported page's origin through CORS.
  • Image and other asset URLs stay as references. They are not embedded. Root-relative public image paths are made absolute against the builder's origin so they can load when the exported file is opened locally.
  • Template parity covers initial content and layout at desktop and mobile sizes; live data-source runtime states are not guaranteed to remain visually identical.

Bundled templates

Templates live in client/features/templates/definitions/. Each one is versioned (schema and version), keeps catalog metadata separate from its content.pages payload, and stores the page as the same AppNode tree the editor uses.

To add a template:

  1. Create a definition in client/features/templates/definitions/ using only supported design-component tags.
  2. Keep catalog metadata (name, description, category, tags, thumbnail) outside the page payload.
  3. Validate it with pageTemplateDefinitionSchema and register it in client/features/templates/registry.ts.
  4. If the template is meant for imported profile data, add dataMapping entries that point to the target component ids and fields.

The CV/resume templates include LinkedIn-shaped mapping notes in their dataMapping blocks.

Documentation

Contributing

See CONTRIBUTING.md for how to open a pull request and the branch naming (gitflow) conventions enforced in this repo.

Security and conduct

Report vulnerabilities privately as described in SECURITY.md. Participation in this project is governed by the Code of Conduct.

License

MIT

About

Simple page builder

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages