PageKit β€” the self-hosted GrapesJS site builder, sold as source. Get early access

Angular page builder

Angular Page Builder with GrapesJS

Build a visual drag-and-drop page builder for Angular with reusable blocks, components, templates, responsive editing and your own publishing workflow.

Visual drag & dropCustom componentsReusable blocksResponsive editingYour backendExtensible with plugins

26k+

GitHub stars

1.4M+

npm downloads / month

100+

Plugins on GJS.Market

$0

License fee, always

See it working

This is what your users would see

Three real GrapesJS editors, loaded only when you ask for them. None of these demos is an Angular application β€” and that is exactly the point. GrapesJS renders into a container element it owns, so the editing surface looks and behaves the same whatever framework hosts the page around it.

Open in a new tab

The stock editor: canvas, blocks, layer tree, style manager and device switcher. This is the foundation you start from before adding a single block of your own.

grapesjs.com/demo.htmlFree

Loads a live third-party editor from grapesjs.com.

Start here

Build visual pages without building the editor from scratch

Building a page builder takes much more than a few Angular components. A production-ready visual editor needs every one of these before anyone can ship a page with it:

  • Drag & drop
  • Canvas
  • Components
  • Blocks
  • Layers
  • Styles
  • Responsive editing
  • Asset management
  • Templates
  • Project storage
  • Export
  • Publishing

GrapesJS provides the visual editing foundation for most of that list, so your Angular application can spend its budget on your product and your business logic instead. The last two β€” where projects are stored and how pages go live β€” stay yours, because they are the parts that have to match your infrastructure.

GrapesJS core is open source under the BSD-3-Clause licence, version 0.23.6, with no licence fee at any scale.

Explore GrapesJS
Architecture

How an Angular page builder works

The editor is one route inside your application, not a replacement for it. Everything above the editing layer stays exactly where Angular teams already put it.

  1. Angular application

    Everything that makes your product yours, unchanged.

    • Authentication
    • Users
    • Billing
    • Routing
    • Business logic
  2. Visual page builder

    A lazy-loaded route, a component that owns the container, and a service that owns the editor instance.

    • Editor route
    • Editor component
    • Editor service
  3. GrapesJS

    The visual editing engine, running inside the container your component provides.

    • Canvas
    • Components
    • Blocks
    • Layers
    • Styles
    • Assets
    • Commands
  4. Your backend

    Where project data, uploads and published output actually live.

    • Your API
    • Your database
    • File storage

Angular owns your application. GrapesJS powers the visual editing layer.

Nothing in the top or bottom tier is provided by the editor. That boundary is what keeps the integration shallow enough to remove later β€” the editor never becomes the thing your product is built around.

Read the Angular integration guide
Capabilities

Everything you need to build a visual editor

Eight subsystems that come with the engine. Each is an API you configure, not a black box you accept as-is.

Drag & drop

Users build pages by dragging components onto the canvas, reordering them and nesting them where you allow it.

Components

Define reusable component types with their own traits, rules about what can be dropped inside them, and your own behaviour.

Blocks

Give users predefined sections and layouts in a palette rather than a list of raw HTML elements.

Style manager

Let users customise typography, spacing, colour and layout through property panels you choose and constrain.

Responsive editing

Preview and restyle a page per breakpoint, using device widths you define rather than a fixed set.

Assets

Manage images and other project assets through an asset manager you can point at your own storage.

Templates

Save finished pages as reusable starting points so the next page begins somewhere other than empty.

Export

Get clean HTML and CSS out of the editor, or read the project JSON and render it however your application prefers.

What is deliberately not on this list: hosting, a CMS, a permission model and publishing infrastructure. Those belong to your application, and the sections below say how they connect.

Customisation

Build your own Angular page builder experience

A generic website builder is rarely the product anyone wants. Every layer of the editor can be replaced with something that matches your application instead.

  1. Your product
  2. Custom components
  3. Custom blocks
  4. Custom templates
  5. Custom commands
  6. Custom UI

Each layer narrows the editor towards your content model. By the last one, users are composing your product β€” not a website.

Register component types that mirror your own domain objects, expose only the traits your backend can act on, and put them in the block palette under your own categories. Users then work with a pricing table or a product grid that your API already understands, rather than with arbitrary markup you have to parse later.

register-blocks.tsts
// Your content model, not a generic website element.
editor.Components.addType('pricing-table', {
  isComponent: (el) => el.dataset?.gjsType === 'pricing-table',
  model: {
    defaults: {
      tagName: 'section',
      droppable: false,
      traits: ['plan', 'currency', 'billingPeriod'],
    },
  },
});

editor.Blocks.add('pricing-table', {
  label: 'Pricing',
  category: 'Your design system',
  content: { type: 'pricing-table' },
});

A component type and the block that inserts it. The trait names become the fields your backend reads.

Blocks & templates

Give users the right building blocks

The difference between an editor people use and one they abandon is usually what is in the palette on day one.

Your blocks

  • Hero
  • Feature grid
  • Pricing
  • Testimonials
  • FAQ
  • Contact
  • CTA
  • Footer

Don't make users start from a blank canvas.

Create reusable blocks and templates that match your application's design system, so every page a user builds is already on-brand and already responsive. GJS.Market ships block sets and template managers you can install instead of authoring the first fifty from scratch.

Browse Blocks & Templates
Storage

Save projects to your Angular backend

GrapesJS serialises a project to JSON and hands it to a storage adapter. What that adapter does is entirely yours.

  1. GrapesJS project data
  2. Angular HttpClient
  3. Your API
  4. Your backend
  5. Your database

The editor never talks to your database. It calls the adapter you registered, and the adapter calls the API you already have.

storage.tsts
editor.Storage.add('angular-backend', {
  async load() {
    return firstValueFrom(this.http.get(`/api/pages/${this.pageId}`));
  },
  async store(data) {
    return firstValueFrom(this.http.put(`/api/pages/${this.pageId}`, data));
  },
});

grapesjs.init({
  container,
  storageManager: { type: 'angular-backend', autosave: true, stepsBeforeSave: 5 },
});

A custom storage adapter wired to your API. Nothing here is specific to GJS.Market β€” it is the editor's documented storage contract.

  • Project data

    Components, styles, pages and assets serialise to a JSON document you can store in any column or collection.

  • Autosave

    The storage manager can save after a configurable number of changes rather than only on an explicit action.

  • Remote storage

    Register a custom adapter and route load and store through Angular's HttpClient, with your own interceptors and auth headers.

  • Versioning

    Because each save is a document, keeping history is a backend decision β€” the editor does not need to know it happened.

  • HTML/CSS output

    Export the rendered markup alongside the project JSON when your delivery path needs static output rather than a re-render.

  • Publishing

    A published page is a separate record with its own lifecycle. Keep it apart from the draft the editor writes to.

You control where project data is stored.

Publishing

From visual editing to production

Authoring and publishing are different problems with different failure modes. The editor solves the first one; the second stays in your infrastructure, where your caching, permissions and rollbacks already live.

  1. Create
  2. Edit
  3. Save
  4. Review
  5. Publish
  6. Live page

Where published output can go

  • CMS

    Write the output back into the content system your organisation already runs.

  • REST API

    Post the project or the rendered markup to an endpoint that owns validation and permissions.

  • Static publishing

    Render pages to files at publish time so the live page carries none of the editor's runtime.

  • Custom backend

    Store, transform and serve the output through the same path your application already uses to serve its pages.

  • CDN

    Push published assets and markup to the edge, with cache invalidation you control.

  • Custom deployment

    Trigger your existing build or deploy pipeline from the publish action.

GrapesJS handles authoring. Your infrastructure can handle publishing.

Multi-tenant

Build a multi-tenant Angular page builder

One deployment of your Angular application, one editor, and a separate world of pages for every customer in it.

Angular SaaS

  • Org A

    • Pages
    • Assets
    • Templates
  • Org B

    • Pages
    • Assets
    • Templates
  • Org C

    • Pages
    • Assets
    • Templates
  • Separate projects per tenant, resolved from the authenticated user rather than from a route parameter.
  • Tenant-scoped asset storage, so an upload can never appear in another customer's asset manager.
  • Templates that can be global, per-plan or per-tenant, depending on what you are selling.
  • Roles and permissions enforced on the server for every load, store and publish call.
  • Per-tenant branding, from the editor chrome down to the block palette.
  • Publishing targets that differ per tenant β€” their domain, their CDN, their pipeline.

None of this is a GrapesJS feature. The editor has no concept of a tenant: it loads the project it is given and stores the project it is handed back. Tenancy is something your Angular application and your backend implement β€” which is also why it can match the isolation model you already have.

Explore SaaS Page Builder
White-label

Make your Angular page builder your own

Nothing about the editor has to look like the editor. Every surface a user touches is configurable, replaceable or removable.

  • Your logo in place of the editor's chrome
  • Your colour tokens, not a third-party theme
  • Custom panels, or your own Angular UI driving the editor through commands
  • Only the blocks your product supports
  • Templates that come from your design system
  • Your vocabulary β€” sections, modules, layouts, whatever your users already say
  • Roles that decide who may edit, who may publish and who may only comment
  • Permissions enforced on the server, reflected in the UI

Turn a visual editor into a native part of your Angular product.

Explore White-Label Page Builder
Integration

Integrate GrapesJS with Angular

The short version, in four steps. The complete guide β€” lifecycle details, wrappers, zoneless change detection, production concerns β€” lives on its own page and goes much further than this.

  1. 1

    Install

    Add the editor to your application. It is a plain npm package with no Angular-specific build step.

  2. 2

    Create an editor service

    Keep the editor instance in an injectable service so the component stays thin and the instance is easy to share, mock and tear down.

  3. 3

    Initialize in ngAfterViewInit

    The container element must be in the DOM before the editor is created, because GrapesJS measures it immediately.

  4. 4

    Destroy correctly in ngOnDestroy

    Call destroy when the route is left. Without it the editor keeps its DOM listeners and the next navigation leaks an instance.

npm install grapesjs

One dependency. No Angular-specific wrapper is required.

page-builder.service.tsts
import { Injectable, NgZone, inject } from '@angular/core';
import grapesjs, { type Editor } from 'grapesjs';

@Injectable({ providedIn: 'root' })
export class PageBuilderService {
  private readonly zone = inject(NgZone);
  private editor?: Editor;

  create(container: HTMLElement): Editor {
    // GrapesJS binds its own DOM listeners to the canvas. Creating it outside
    // Angular keeps every drag frame from scheduling change detection.
    this.editor = this.zone.runOutsideAngular(() =>
      grapesjs.init({
        container,
        height: '100%',
        fromElement: false,
        storageManager: false,
      })
    );

    return this.editor;
  }

  destroy(): void {
    this.editor?.destroy();
    this.editor = undefined;
  }
}

The service owns the instance and its lifetime; the component owns only the container.

page-builder.component.tsts
import {
  AfterViewInit,
  Component,
  ElementRef,
  OnDestroy,
  inject,
  viewChild,
} from '@angular/core';
import { PageBuilderService } from './page-builder.service';

@Component({
  selector: 'app-page-builder',
  standalone: true,
  template: '<div #canvas class="builder"></div>',
  styles: '.builder { height: 100vh; }',
})
export class PageBuilderComponent implements AfterViewInit, OnDestroy {
  private readonly builder = inject(PageBuilderService);
  private readonly canvas = viewChild.required<ElementRef<HTMLElement>>('canvas');

  ngAfterViewInit(): void {
    // The container has to be in the DOM first: GrapesJS measures it on init.
    this.builder.create(this.canvas().nativeElement);
  }

  ngOnDestroy(): void {
    // Without this the editor keeps its listeners after the route changes.
    this.builder.destroy();
  }
}

Create after the view exists, destroy when it goes away. That pair is most of the integration.

Need the complete Angular integration guide?

Wrapper options, zoneless change detection, lazy-loaded editor routes, asset handling and the production checklist are covered end to end there.

Read the Angular Integration Guide
Change detection

Working with Angular change detection

GrapesJS emits its own events, and those events do not come from Angular. Coordinating the two is a few lines, but skipping it produces the two bugs every integration hits first.

  1. GrapesJS event
  2. NgZone.run()
  3. Angular state
  4. UI update
page-builder.component.tsts
editor.on('storage:end:store', () => {
  // Editor events fire outside Angular because the editor was created there.
  // Re-enter the zone before touching state the template renders.
  this.zone.run(() => this.lastSavedAt.set(new Date()));
});

Re-entering the zone in the one handler that updates rendered state.

Create the editor inside runOutsideAngular so canvas interaction does not schedule change detection on every frame, then re-enter the zone in the handful of event handlers that actually update state your template renders. On a zoneless application the same handlers update signals instead, and the outer wrapper is no longer needed.

More on Angular lifecycle and zones
Server-side rendering

Angular SSR and GrapesJS

GrapesJS needs a browser DOM. Under Angular SSR or Angular Universal that means the editor is created in the browser only β€” the route around it still renders on the server as normal.

Guard the initialization with isPlatformBrowser and return early on the server. The rest of the route is unchanged: guards, resolvers and the surrounding markup keep their server-rendered behaviour, and only the editor container arrives empty.

page-builder.component.tsts
import { PLATFORM_ID, inject } from '@angular/core';
import { isPlatformBrowser } from '@angular/common';

export class PageBuilderComponent implements AfterViewInit {
  private readonly isBrowser = isPlatformBrowser(inject(PLATFORM_ID));

  ngAfterViewInit(): void {
    // There is no DOM on the server and GrapesJS needs one, so the editor is
    // created in the browser only. The rest of the route still renders on the
    // server as usual.
    if (!this.isBrowser) return;
    this.builder.create(this.canvas().nativeElement);
  }
}

The whole SSR adjustment: one platform check before the editor is created.

TypeScript & AOT

Angular, TypeScript and AOT

The integration is ordinary Angular code, which is the main thing worth saying about it.

  • TypeScript-friendly

    The editor ships its own type definitions, so the instance, its configuration and its events are typed at the call site.

  • Angular lifecycle

    Creation and teardown hang off ngAfterViewInit and ngOnDestroy β€” no manual bootstrapping outside the component tree.

  • AOT-compatible

    Nothing in the integration depends on runtime template compilation, so the editor route builds like any other lazy-loaded route.

  • Browser-only initialization

    Where SSR is in play, only the editor creation is browser-guarded; the rest of the component compiles and renders normally.

Build vs adopt

Build an Angular page builder from scratch vs GrapesJS

Every capability below has to exist before a visual editor is usable. The only question is which of them you write yourself.

CapabilityFrom scratchGrapesJS
Visual canvasBuildIncluded
Drag & dropBuildIncluded
ComponentsBuildIncluded
BlocksBuildExtensible
StylingBuildIncluded
Responsive editingBuildIncluded
AssetsBuildExtensible
TemplatesBuildExtensible
StorageBuildExtensible
ExportBuildExtensible
Angular integrationBuildIntegrate

"Extensible" means the subsystem exists and has a documented API you point at your own implementation β€” not that it arrives pre-wired to your backend. Verified against GrapesJS 0.23.6 on 2026-09-03.

Build your Angular product. Don't rebuild the visual editing engine.

  1. GrapesJS
  2. Angular integration
  3. Blocks
  4. Templates
  5. Forms
  6. Storage
  7. Assets
  8. Export
  9. Publishing

The stack a working builder ends up with. GrapesJS covers the first layer; the rest is yours to assemble, install or buy.

Plugins

Extend your Angular page builder with plugins

The engine gives you the editing surface. Everything a specific product needs on top of it β€” the block palette, the template system, rich text, persistence, the exit path to production β€” is where GJS.Market plugins come in. Every listing below is a real product, priced as shown.

Build or extend

Start with the editor. Add what your product needs.

Both columns end with a working builder. They differ in how much of it you are still maintaining in two years.

GrapesJS provides the visual editing foundation. GJS.Market plugins let you extend your builder with additional capabilities instead of building every feature internally.

Build everything yourself

  • More development before the first usable release
  • More maintenance as browsers, Angular and your design system move
  • More internal code that only your team understands
  • Every editor subsystem becomes something you are on call for

Extend with plugins

  1. Install what the product actually needs
  2. Configure it against your content model
  3. Customise the parts your users see
  4. Ship, and keep your budget on your own features
Audience

Who builds Angular page builders?

Five recurring shapes, and what each of them is really buying with a visual editor.

SaaS companies

Add visual editing to a product whose customers currently ask support to change a page for them.

Agencies

Build a custom editing environment per client instead of handing over a CMS nobody wanted.

CMS platforms

Add visual editing without spending a roadmap year writing an editor engine from scratch.

Marketing platforms

Let marketers create and change pages without a developer in the loop for every headline.

Enterprise teams

Create controlled internal editing workflows, where what can be edited is as important as what can be built.

Choose your path

Choose the right page builder approach

Four ways to ship a visual editor. They overlap, but they start from different constraints β€” and picking the wrong one shows up late.

Building the same thing on another framework? The argument is identical for React, Next.js and Vue β€” only the lifecycle code changes. React page builder, Next.js page builder, Vue page builder.

Performance

Performance considerations

An editor is a heavy application and a published page is not. Treating them as one bundle is the mistake worth avoiding early.

  1. Lazy-load the editor route

    Users who never open the builder should never download it. A lazy route keeps the editor out of your main bundle.

  2. Avoid unnecessary re-renders

    Create the editor outside Angular's zone and re-enter it only in the handlers that update rendered state.

  3. Optimise large asset libraries

    Paginate the asset manager against your API rather than handing it several thousand images at once.

  4. Initialize only when needed

    Create the instance when the editor is actually shown, not when the surrounding component mounts.

  5. Keep editor code out of published pages

    Published output is HTML and CSS. Nothing about the editor needs to ship with it.

The editor runtime and the published page do not need to have the same performance requirements.

Security

Security considerations

A visual editor accepts user-authored content and writes it back to your system. Every one of these belongs on the server side of that exchange.

  1. Server-side authorization

    Check on every load, store and publish call whether this user may act on this project.

  2. Tenant isolation

    Resolve the tenant from the session, never from a parameter the client can change.

  3. Upload validation

    Validate type and size server-side, and serve uploads from an origin that cannot execute them.

  4. API authentication

    The storage adapter runs in the browser. Its endpoints need the same authentication as the rest of your API.

  5. Content sanitisation

    Where editors may embed custom code, sanitise on the server before that markup is served to anyone else.

  6. Protected publishing endpoints

    Publishing changes what the public sees. Rate-limit it, log it, and gate it behind its own permission.

  7. Server-side permission checks

    Hiding a button changes the UI, not the API. Every rule the UI implies must also exist behind it.

Never rely only on client-side permissions.

Services

Need help building your Angular page builder?

Need help integrating, extending or customising GrapesJS inside your Angular application? Our team can help with integration, custom plugins, UI customisation and production implementation.

  • Angular integration and editor architecture
  • Custom components, blocks and plugins
  • UI customisation and white-labelling
  • Storage, publishing and production rollout
Explore Services
FAQ

Angular page builder questions

What is an Angular page builder?

A visual editor inside an Angular application that lets users assemble pages by dragging components onto a canvas instead of writing markup. The Angular app owns routing, authentication and data; the editor owns the editing surface.

Can I use GrapesJS with Angular?

Yes. GrapesJS is framework-agnostic: it renders into a container element you give it, so it works inside an Angular component like any other DOM-based library.

Is GrapesJS an Angular page builder?

No β€” it is the visual editing engine an Angular page builder is built on. There is no official Angular wrapper; you integrate the core library directly, which is a component and a service.

How do I integrate GrapesJS with Angular?

Install the package, keep the instance in an injectable service, create it in ngAfterViewInit once the container is in the DOM, and destroy it in ngOnDestroy. The full guide covers wrappers, zones and production concerns.

Can I create custom blocks?

Yes. Blocks are registered through the block manager with your own label, category and content, so the palette can contain only sections your product supports.

Can I create custom components?

Yes. Component types are registered with their own traits, drop rules and behaviour, which is how the editor is narrowed from generic HTML down to your content model.

Can I create reusable templates?

Yes. A saved project can be reloaded as the starting point for a new page. Template libraries and managers are also available as plugins if you would rather not build the UI.

Can I save projects to my Angular backend?

Yes. Register a custom storage adapter whose load and store methods call your API through HttpClient, so your interceptors, auth headers and error handling apply as usual.

Can I use my own database?

Yes. The editor produces a JSON document and never talks to a database itself, so where that document is stored is entirely a backend decision.

Can I build a landing page builder with Angular?

Yes, and it is one of the most common uses: a restricted block palette, on-brand templates and a publish action that writes to wherever your marketing pages are served from.

Can I build an Angular CMS editor?

Yes. The editor replaces the form-based editing screen; your CMS keeps ownership of content types, workflow and permissions.

Can I build a form builder with Angular?

Yes. Register your own field components as component types with traits for validation and naming, so what users assemble maps onto a schema your backend understands.

Can I build a multi-tenant Angular page builder?

Yes, but tenancy is your application's job. The editor has no concept of a tenant β€” your backend resolves which project, assets and templates the current user may see.

Can I create a white-label Angular builder?

Yes. Panels, icons, colours, block categories and terminology are all configurable, and you can drive the editor from your own Angular UI through its command API.

Does GrapesJS work with Angular SSR?

The surrounding route renders on the server as normal; the editor itself is created in the browser only. Guard initialization with isPlatformBrowser and return early on the server.

How does GrapesJS work with Angular's NgZone?

Create the editor inside runOutsideAngular so canvas interaction does not trigger change detection constantly, then use NgZone.run inside the few event handlers that update state your template renders.

Can I use TypeScript?

Yes. GrapesJS ships its own type definitions, so the editor instance, its configuration object and its events are typed in an ordinary Angular TypeScript codebase.

Can I extend the builder with plugins?

Yes. Plugins are functions that receive the editor and register components, blocks, commands or panels. GJS.Market lists free and commercial plugins for blocks, rich text, storage, assets and export.

Get started

Build your Angular page builder without starting from scratch

Use Angular for your application and GrapesJS for the visual editing experience. Add your own components, blocks, templates, storage and publishing workflow β€” then extend the builder with GJS.Market plugins when you need more.

Start

Get Started

Install the editor, mount it on a container inside an Angular component, and have something on screen this afternoon.

Get Started
Extend

Browse Plugins

Blocks, templates, rich text, storage and export β€” install the capabilities your product needs instead of writing them.

Browse Plugins
Integrate

View Angular Guide

Lifecycle, zones, SSR, wrappers and the production checklist, covered end to end on the integration page.

View Angular Guide

Your Angular app. Your editor. Your product.