GrapesJS Angular एकीकरण

GrapesJS Angular:Angular के साथ एक विज़ुअल एडिटर बनाएं

ड्रैग-एंड-ड्रॉप पेज बिल्डर, CMS संपादक, लैंडिंग पेज बिल्डर, ईमेल संपादक और व्हाइट-लेबल विज़ुअल संपादन अनुभव बनाने के लिए ओपन-सोर्स GrapesJS विज़ुअल एडिटर को Angular एप्लिकेशन में एकीकृत करें।

खुला स्रोतस्व-होस्टेडHTML और CSS आउटपुटएक्स्टेंसिबलAngular संगत

26k+

GitHub सितारे

1.4M+

npm डाउनलोड/माह

100+

प्लगइन्स GJS.Market पर

$0

लाइसेंस शुल्क

लाइव संपादक

GrapesJS एप्लिकेशन में Angular आज़माएं

एक नए टैब में खोलें

स्टॉक GrapesJS बिल्ड - वह संपादक जो आपको मानक प्रीसेट के साथ 'grapesjs.init()' से मिलता है, इससे पहले कि कोई प्लगइन जोड़ा जाए। दाएं पैनल से एक ब्लॉक खींचें, उसका चयन करें, और स्टाइल मैनेजर में इसकी टाइपोग्राफी और रिक्ति को संपादित करें।

grapesjs.com/demo.htmlनिःशुल्क

grapesjs.com से एक तृतीय-पक्ष पृष्ठ लोड करता है। जब तक आप क्लिक नहीं करते तब तक कुछ भी अनुरोध नहीं किया जाता है।

ये लाइव GrapesJS बिल्ड हैं, न कि Angular डेमो - और यही बात है। GrapesJS एक कंटेनर तत्व में प्रस्तुत करता है जो पूरी तरह से मालिक है, इसलिए कैनवास, ब्लॉक, स्टाइल मैनेजर, उत्तरदायी पूर्वावलोकन, परिसंपत्ति बीनने वाला और इतिहास पूर्ववत करें जिसे आप नीचे चलाते हैं, एक बार Angular घटक उस कंटेनर को होस्ट करता है।

  1. Angular application
  2. GrapesJS editor
  3. HTML + CSS + project data
  4. Your backend / CMS / SaaS

Angular आपके एप्लिकेशन को शक्ति प्रदान करता है। GrapesJS दृश्य संपादन अनुभव को शक्ति प्रदान करता है। जो सामने आता है वह HTML, CSS और एक प्रोजेक्ट JSON दस्तावेज़ है जिसे आपका अपना बैकएंड स्टोर करता है।

सीधा जवाब

क्या आप GrapesJS का उपयोग Angular के साथ कर सकते हैं?

हाँ

GrapesJS फ्रेमवर्क-अज्ञेयवादी है और इसे Angular अनुप्रयोगों में एकीकृत किया जा सकता है। आप संपादक को Angular जीवनचक्र हुक के माध्यम से प्रारंभ करते हैं, संपादक इंस्टेंस को अपने नियंत्रण में रखते हैं, GrapesJS ईवेंट को Angular एप्लिकेशन लॉजिक से कनेक्ट करते हैं, और अपने स्वयं के बैकएंड के माध्यम से प्रोजेक्ट डेटा को बनाए रखते हैं।

  • GrapesJS एक सादा जावास्क्रिप्ट लाइब्रेरी है जिसमें कोई फ्रेमवर्क बाइंडिंग नहीं है - इसे DOM तत्व की आवश्यकता होती है और कुछ नहीं।
  • इसे ngAfterViewInit में प्रारंभ करें, एक बार कंटेनर तत्व वास्तव में DOM में मौजूद हो जाता है।
  • इसे ngOnDestroy में नष्ट करें ताकि श्रोताओं, DOM नोड्स और पूर्ववत स्टैक घटक के साथ जारी किए जाएं।
  • संपादक इंस्टेंस को एक सेवा में रखें यदि एक से अधिक घटकों को उससे बात करने की आवश्यकता है।
  • Editor ईवेंट सामान्य उत्सर्जक घटनाएं हैं - उन्हें संकेतों, वेधशालाओं या NgZone में पुल करें जैसा कि आपके ऐप की आवश्यकता है।
  • भंडारण और संपत्ति आपकी हैं: GrapesJS आपके समापन बिंदुओं को कॉल करता है, यह बैकएंड शिप नहीं करता है।

कोई आधिकारिक Angular आवरण नहीं है। GrapesJS परियोजना एक React आवरण और कोई Angular समकक्ष नहीं रखती है, इसलिए Angular एकीकरण का अर्थ है एक घटक लिखना - नीचे दिए गए उदाहरण में लगभग तीस पंक्तियाँ - या अपने स्वयं के गुणों के आधार पर किसी तृतीय-पक्ष पैकेज का मूल्यांकन करना।

काम करने वाले उदाहरण पर जाएं
श्रम विभाजन

GrapesJS के लिए Angular क्या है?

GrapesJS विज़ुअल एडिटिंग इंजन है। Angular एप्लिकेशन फ्रेमवर्क है। लगभग हर एकीकरण समस्या जो लोगों को मिलती है, वह उनमें से एक से दूसरे का काम करने की उम्मीद करने से आती है, इसलिए उनके बीच की रेखा के बारे में स्पष्ट होना उचित है।

Angular

Angular एप्लिकेशन का मालिक है

कैनवास के चारों ओर सब कुछ: उपयोगकर्ता कौन है, उन्हें क्या करने की अनुमति है, और परिणाम कहां जाता है।

  • रूटिंग
  • प्रमाणीकरण
  • आवेदन UI
  • उपयोगकर्ता
  • अनुमतियां
  • बिलिंग
  • API परत
  • आवेदन की स्थिति
GrapesJS

GrapesJS संपादन सतह का मालिक है

कैनवास के अंदर सब कुछ: क्या खींचा जा सकता है, चुना जा सकता है, स्टाइल किया जा सकता है और निर्यात किया जा सकता है।

  • कैंवस
  • अवयव
  • ब्लॉक
  • शैली प्रबंधक
  • परिसंपत्ति प्रबंधक
  • आदेश
  • भंडारण प्रबंधक
  • डिवाइस मैनेजर

Angular आपका आवेदन है। GrapesJS आपका विज़ुअल एडिटिंग इंजन है।

सेट अप

GrapesJS को Angular में स्थापित करें

एक निर्भरता और एक स्टाइलशीट। GrapesJS अपने स्वयं के CSS को शिप करता है, और इसके बिना संपादक माउंट करता है लेकिन अनस्टाइल मार्कअप के रूप में प्रस्तुत करता है - जो कि पहला एकीकरण टूटा हुआ दिखने का सबसे आम कारण है।

1 - निर्भरता जोड़ें

npm install grapesjs

2 - स्टाइलशीट रजिस्टर करें

angular.jsonjson
// angular.json → projects.<app>.architect.build.options
{
  "styles": [
    "src/styles.css",
    "node_modules/grapesjs/dist/css/grapes.min.css"
  ]
}

स्टाइलशीट को angular.json में पंजीकृत करना इसे विश्व स्तर पर लागू करता है। यदि संपादक एक आलसी-लोड किए गए मार्ग पर रहता है और आप हर जगह CSS के लिए भुगतान नहीं करना चाहते हैं, तो इसे इसके बजाय संपादक घटक की अपनी स्टाइलशीट के अंदर आयात करें।

ngAfterViewInit क्यों?

GrapesJS को संलग्न करने के लिए एक वास्तविक तत्व की आवश्यकता होती है, और यह उस तत्व को मापता है क्योंकि यह प्रारंभ होता है। ngOnInit में टेम्पलेट अभी तक प्रस्तुत नहीं किया गया है, इसलिए एक @ViewChild संदर्भ अभी भी अपरिभाषित है और कॉल पूरी तरह से विफल हो जाती है। ngAfterViewInit Angular द्वारा घटक का दृश्य बनाने के बाद चलता है, जो कि कंटेनर मौजूद होने का पहला क्षण है। वही तर्क नीचे दी गई स्टाइलशीट में ऊंचाई नियम की व्याख्या करता है: बिना किसी हल की ऊंचाई वाला एक तत्व एक संपादक बनाता है जो त्रुटि के बिना आरंभ करता है और कुछ भी प्रदर्शित नहीं करता है।

इससे पहले कि आप घटक लिखें

कंटेनर तुम्हारा नहीं है

GrapesJS आपके द्वारा सौंपे गए तत्व की सामग्री को बदल देता है। उस तत्व के अंदर Angular टेम्पलेट सामग्री को प्रस्तुत न करें और इसके तहत किसी भी चीज़ से न बंधें।

इसे ऊंचाई दें

होस्ट तत्व को आरंभीकरण से पहले एक हल की गई ऊंचाई की आवश्यकता होती है। एक शून्य-ऊंचाई वाला कंटेनर एक संपादक को माउंट करता है जिसे आप नहीं देख सकते हैं।

प्रति घटक एक उदाहरण

संपादक के लिए एक ही संदर्भ रखें और इसे ngOnDestroy में नष्ट कर दें। एक मार्ग पर दो लाइव उदाहरण कीबोर्ड शॉर्टकट पर लड़ेंगे।

प्रकार शामिल हैं

grapesjs पैकेज अपनी TypeScript परिभाषाओं को शिप करता है, इसलिए Editor, Component और ProjectData एक अलग @types पैकेज के बिना आयात योग्य हैं।

न्यूनतम कार्य उदाहरण

एक पूर्ण Angular संपादक घटक

तीन फ़ाइलें, कुछ भी उत्पन्न नहीं हुआ, कुछ भी छिपा नहीं है। उन्हें Angular एप्लिकेशन में कॉपी करें और आपके पास एक मार्ग पर एक कार्यशील दृश्य संपादक है। इस पृष्ठ पर बाद में सब कुछ - भंडारण, संपत्ति, कस्टम घटक, प्लगइन्स - इस घटक के अतिरिक्त है, न कि इसका पुनर्लेखन।

editor.component.tsts
// editor.component.ts
import {
  AfterViewInit,
  Component,
  ElementRef,
  OnDestroy,
  ViewChild,
} from '@angular/core';
import grapesjs, { type Editor } from 'grapesjs';

@Component({
  selector: 'app-editor',
  templateUrl: './editor.component.html',
  styleUrl: './editor.component.css',
})
export class EditorComponent implements AfterViewInit, OnDestroy {
  // Resolved by the time ngAfterViewInit runs — that is the whole reason
  // initialisation lives there and not in ngOnInit.
  @ViewChild('editorHost') private host!: ElementRef<HTMLDivElement>;

  private editor?: Editor;

  ngAfterViewInit(): void {
    this.editor = grapesjs.init({
      container: this.host.nativeElement,
      height: '100%',
      width: 'auto',
      fromElement: false,
      // No persistence yet. Wire your own API before shipping — see Storage.
      storageManager: false,
      blockManager: {
        blocks: [
          {
            id: 'section',
            label: 'Section',
            category: 'Layout',
            content: '<section class="section"><h2>Headline</h2></section>',
          },
          {
            id: 'text',
            label: 'Text',
            category: 'Basic',
            content: { type: 'text', content: 'Edit me' },
          },
          { id: 'image', label: 'Image', category: 'Basic', content: { type: 'image' } },
        ],
      },
    });
  }

  ngOnDestroy(): void {
    // GrapesJS owns DOM nodes, document listeners and an undo stack. Angular
    // removes the host element; only destroy() releases the rest.
    this.editor?.destroy();
    this.editor = undefined;
  }
}
editor.component.htmlhtml
<!-- editor.component.html -->
<!-- GrapesJS takes this element over completely. Do not render Angular
     content inside it — the editor owns everything below #editorHost. -->
<div class="editor-shell">
  <div #editorHost class="editor-host"></div>
</div>
editor.component.csscss
/* editor.component.css */
.editor-shell {
  display: block;
  block-size: 100dvh;
}

/* GrapesJS measures its container at init. A host with no resolved height
   produces an editor that mounts successfully and renders nothing. */
.editor-host {
  block-size: 100%;
}

यही संपूर्ण एकीकरण है। फिर से पढ़ने लायक हिस्से दो जीवनचक्र हुक हैं: ngAfterViewInit में आरंभीकरण क्योंकि कंटेनर को पहले मौजूद होना चाहिए, और destroy() ngOnDestroy में क्योंकि Angular होस्ट तत्व को हटाने से दस्तावेज़ से जुड़ा GrapesJS जारी नहीं होता है।

संपादक को अपने मार्ग पर लोड करें

संपादक अधिकांश अनुप्रयोगों में सबसे भारी चीज है जिसमें एक होता है। इसे आलसी रूप से लोड किए गए मार्ग के पीछे रखने से यह हर उस उपयोगकर्ता के लिए प्रारंभिक बंडल से बाहर रहता है जो इसे कभी नहीं खोलता है।

app.routes.tsts
// app.routes.ts — the editor is the heaviest route in the app. Load it last.
import type { Routes } from '@angular/router';

export const routes: Routes = [
  { path: '', loadComponent: () => import('./home/home.component').then((m) => m.HomeComponent) },
  {
    path: 'pages/:id/edit',
    loadComponent: () => import('./editor/editor.component').then((m) => m.EditorComponent),
  },
];
जीवनचक्र

GrapesJS को Angular जीवनचक्र के साथ एकीकृत करना

संपादक का जीवनकाल घटक से बंधा होना चाहिए। चार टुकड़े उस काम को करते हैं, और उनमें से प्रत्येक गायब होने पर पहचानने योग्य तरीके से विफल हो जाता है।

@ViewChild

कंटेनर तत्व का संदर्भ प्राप्त करता है। इसे टेम्पलेट संदर्भ चर द्वारा क्वेरी करें, न कि CSS चयनकर्ता द्वारा, इसलिए मार्कअप का एक रिफैक्टर चुपचाप लुकअप को तोड़ नहीं सकता है।

ngAfterViewInit

पहला हुक जो घटक के दृश्य के बाद चलता है, मौजूद है। यहां आरंभ करें। पहले आरंभ करने से आपको एक अपरिभाषित तत्व संदर्भ मिलता है।

संपादक उदाहरण

इसे एक निजी क्षेत्र में, या एक सेवा में रखें यदि कहीं और टूलबार घटक को कमांड ट्रिगर करने की आवश्यकता होती है। बाद में आप जो कुछ भी करते हैं वह इस एक ऑब्जेक्ट से होकर गुजरता है।

ngOnDestroy

editor.destroy() पर कॉल करें। यह संपादक के DOM को हटा देता है, अपने दस्तावेज़-स्तरीय श्रोताओं को अलग करता है और पूर्ववत स्टैक को त्याग देता है। इसे छोड़ना एक रिसाव है जो नेविगेशन से बच जाता है।

संपादक कंटेनर मौजूद होने से पहले GrapesJS प्रारंभ न करें।

यह वह त्रुटि है जो अधिकांश "GrapesJS Angular" रिपोर्ट में काम नहीं करती है। ngOnInit में, और किसी भी कंस्ट्रक्टर में, दृश्य नहीं बनाया गया है - कंटेनर संदर्भ अपरिभाषित है और आरंभीकरण फेंकता है। यदि कंटेनर एक @if ब्लॉक या एक आस्थगित दृश्य के अंदर है, तो ngAfterViewInit भी पर्याप्त नहीं है: तब तक प्रतीक्षा करें जब तक कि वह शाखा वास्तव में आपके शुरू होने से पहले प्रस्तुत न हो जाए।

पहचान बदलें

GrapesJS और Angular परिवर्तन का पता लगाना

GrapesJS बड़ी संख्या में श्रोताओं को अपने कैनवास से जोड़ता है और उन्हें लगातार आग लगाता है जबकि एक घटक को खींचा या आकार दिया जा रहा है। एक ज़ोन-आधारित Angular एप्लिकेशन में उन श्रोताओं में से हर एक परिवर्तन-पहचान पास शेड्यूल करता है, भले ही आपके घटक ट्री में कुछ भी नहीं बदला हो।

editor.component.ts (अंश)ts
// editor.component.ts (excerpt)
import { Component, NgZone, inject, signal } from '@angular/core';

export class EditorComponent {
  private readonly zone = inject(NgZone);

  readonly selectedTag = signal('');
  readonly savedAt = signal<Date | null>(null);

  private mount(host: HTMLElement): void {
    // The canvas fires pointer events continuously while a block is being
    // dragged. Creating the editor outside the zone keeps those from
    // scheduling a change-detection pass on every frame.
    this.zone.runOutsideAngular(() => {
      const editor = grapesjs.init({ container: host, height: '100%' });

      // Re-enter only where editor state has to become Angular state.
      editor.on('component:selected', (component) => {
        this.zone.run(() => this.selectedTag.set(component.get('tagName') ?? ''));
      });

      editor.on('storage:end:store', () => {
        this.zone.run(() => this.savedAt.set(new Date()));
      });

      this.editor = editor;
    });
  }
}

// Zoneless applications (provideZonelessChangeDetection) have no zone to
// leave. Set signals from the same editor events and drop NgZone entirely.
  • NgZone.runOutsideAngular() के अंदर संपादक बनाएं ताकि कैनवास गतिविधि परिवर्तन का पता लगाने को प्रेरित न करे।
  • केवल उन हैंडलर्स में NgZone.run() के साथ पुनः दर्ज करें जहां संपादक स्थिति को Angular स्थिति बनना है - एक चयन, एक सेव टाइमस्टैम्प, एक सत्यापन त्रुटि।
  • यदि आपके UI में कुछ भी संपादक की स्थिति को दर्शाता नहीं है, तो आपको कभी भी फिर से प्रवेश करने की आवश्यकता नहीं है।
  • एक ज़ोनलेस एप्लिकेशन (provideZonelessChangeDetection) में छोड़ने के लिए कोई क्षेत्र नहीं है: एक ही संपादक घटनाओं से संकेतों को लिखें और NgZone को पूरी तरह से छोड़ दें।

अंगूठे का एक नियम

आरंभीकरण के समय एक बार ज़ोन छोड़ दें। उन विशिष्ट घटनाओं पर संकीर्ण रूप से पुनः प्रवेश करें, जिन्हें आपका इंटरफ़ेस सुनता है। प्रत्येक संपादक कॉलबैक को NgZone.run() में लपेटने से ठीक वही परिवर्तन-पता लगाने वाला मंथन वापस मिल जाता है जिससे बचने के लिए आपने क्षेत्र छोड़ा था।

सर्वर-साइड रेंडरिंग

क्या GrapesJS Angular SSR के साथ काम करता है?

संपादक ब्राउज़र में चलता है। GrapesJS वास्तविक DOM से अपना कैनवास बनाता है - यह तत्वों को मापता है, एक iframe बनाता है और दस्तावेज़ श्रोताओं को संलग्न करता है - इसलिए आरंभीकरण ब्राउज़र संदर्भ में होना चाहिए और सर्वर रेंडर के दौरान नहीं चलना चाहिए। वे मार्ग जो केवल प्रकाशित आउटपुट प्रदर्शित करते हैं, अप्रभावित हैं: यह सादा HTML और CSS है और सर्वर पर किसी और चीज़ की तरह रेंडर करता है।

editor.component.tsts
// editor.component.ts — browser-only initialisation
import {
  AfterViewInit,
  Component,
  ElementRef,
  OnDestroy,
  PLATFORM_ID,
  ViewChild,
  inject,
} from '@angular/core';
import { isPlatformBrowser } from '@angular/common';
import type { Editor } from 'grapesjs';

export class EditorComponent implements AfterViewInit, OnDestroy {
  @ViewChild('editorHost') private host!: ElementRef<HTMLDivElement>;

  private readonly isBrowser = isPlatformBrowser(inject(PLATFORM_ID));
  private editor?: Editor;

  async ngAfterViewInit(): Promise<void> {
    if (!this.isBrowser) return;

    // A dynamic import keeps the editor out of the server bundle and off the
    // critical path of every route that never opens it.
    const { default: grapesjs } = await import('grapesjs');
    this.editor = grapesjs.init({ container: this.host.nativeElement });
  }

  ngOnDestroy(): void {
    this.editor?.destroy();
  }
}
  • गार्ड आरंभीकरण इसलिए यह केवल ब्राउज़र में चलता है - प्लेटफ़ॉर्म चेक और नीचे रेंडर हुक दोनों ऐसा करते हैं।
  • लाइब्रेरी को गतिशील रूप से आयात करें ताकि यह कभी भी सर्वर बंडल में प्रवेश न करे।
  • सर्वर पास के दौरान एक ही आकार के प्लेसहोल्डर को रेंडर करें ताकि संपादक के प्रकट होने पर लेआउट शिफ्ट से बचा जा सके।
  • उन मार्गों को प्रकाशित करें जो केवल संग्रहीत HTML और CSS को प्रस्तुत करते हैं, उन्हें किसी गार्ड की आवश्यकता नहीं है।

रेंडर-हुक विकल्प

हाल के Angular संस्करण एक रेंडर हुक प्रदान करते हैं जिसका कॉलबैक केवल ब्राउज़र प्लेटफ़ॉर्म पर चलता है और सर्वर पर कभी नहीं। जहां यह उपलब्ध है, यह प्लेटफ़ॉर्म चेक के बिना समान गारंटी व्यक्त करता है, और यह स्वाभाविक रूप से सिग्नल-आधारित दृश्य प्रश्नों के साथ जुड़ता है।

editor.component.ts (रेंडर हुक)ts
// The same guard, expressed with the render hook instead of a platform check.
import { Component, ElementRef, afterNextRender, viewChild } from '@angular/core';
import type { Editor } from 'grapesjs';

@Component({ selector: 'app-editor', template: '<div #editorHost></div>' })
export class EditorComponent {
  private readonly host = viewChild.required<ElementRef<HTMLDivElement>>('editorHost');
  private editor?: Editor;

  constructor() {
    // afterNextRender callbacks run on browser platforms only — they never
    // execute on the server, so no isPlatformBrowser check is needed.
    afterNextRender(async () => {
      const { default: grapesjs } = await import('grapesjs');
      this.editor = grapesjs.init({ container: this.host().nativeElement });
    });
  }
}

चुनने से पहले जांचें कि आपका Angular संस्करण इनमें से किसका समर्थन करता है। दोनों पैटर्न एक ही नियम को लागू करने के लिए मौजूद हैं - संपादक ब्राउज़र में इनिशियलाइज़ करता है और कहीं और नहीं। angular.dev

एनाटॉमी

Angular के साथ GrapesJS पेज बिल्डर बनाएं

एक पेज बिल्डर एक विशेषता नहीं है। यह नौ उप-प्रणालियाँ हैं जिन्हें एक दूसरे से सहमत होना पड़ता है, और GrapesJS सभी नौ जहाजों को भेजता है। यह सिंहावलोकन है; उत्पाद-स्तरीय निर्णय - मूल्य निर्धारण, भूमिकाएँ, टेम्पलेट्स, प्रकाशन वर्कफ़्लो - नीचे लिंक किए गए समर्पित गाइड से संबंधित हैं।

  • GrapesJS

    कैंवस

    संपादन योग्य सतह, अपने स्वयं के iframe में प्रस्तुत की गई है ताकि पृष्ठ शैलियाँ आपके व्यवस्थापक UI में लीक न हो सकें।

  • GrapesJS

    अवयव

    प्रत्येक तत्व के पीछे टाइप किया गया मॉडल: यह क्या है, यह क्या स्वीकार करता है, और यह किन सेटिंग्स को उजागर करता है।

  • GrapesJS

    ब्लॉक प्रबंधक

    पैलेट उपयोगकर्ता खींचते हैं। एक ब्लॉक एक घटक प्रकार में मैप की गई सामग्री का एक नामित टुकड़ा है।

  • GrapesJS

    शैली प्रबंधक

    CSS संपादन पैनल, कॉन्फ़िगर करने योग्य है कि किसी दिए गए उपयोगकर्ता को किस गुण को बदलने की अनुमति है।

  • Plugin

    परिसंपत्ति प्रबंधक

    छवि और मीडिया चयन। इसके पीछे अपलोड समापन बिंदु आपका है, इसलिए यहां प्लगइन्स ज्यादातर इसे एक प्रदाता से जोड़ते हैं।

  • आपका Angular ऐप

    भंडारण प्रबंधक

    लोड करें और सहेजें। GrapesJS अनुबंध को परिभाषित करता है और आपके API को कॉल करता है - दृढ़ता ही आपके आवेदन का है।

  • GrapesJS

    आदेश

    नामित, कॉल करने योग्य क्रियाएं — पूर्ववत करें, पूर्वावलोकन करें, निर्यात करें, और कुछ भी जो आप टूलबार बटन के लिए स्वयं को पंजीकृत करते हैं।

  • GrapesJS

    डिवाइस मैनेजर

    कैनवास के उत्तरदायी ब्रेकपॉइंट का पूर्वावलोकन और स्टाइल किया जा सकता है।

  • GrapesJS

    पैनलों

    संपादक का अपना क्रोम - बटन, टूलबार और क्षेत्र, सभी बदली जा सकती हैं यदि संपादक मौजूदा शेल के अंदर बैठता है।

इसे कौन बनाता हैGrapesJSPluginआपका Angular ऐप

नौ में से आठ संपादक के साथ या एक प्लगइन के साथ जहाज करते हैं। जो अपरिहार्य रूप से आपका है वह भंडारण है - जो कि आपके उपयोगकर्ताओं, आपकी अनुमतियों और आपके डेटाबेस के बारे में भी जानना है।

एक पूर्ण Angular पेज बिल्डर बनाएं
यह कहाँ बैठता है

Angular एप्लिकेशन के अंदर संपादक

बाहर से अंदर पढ़ें, यह संपूर्ण एकीकरण है। GrapesJS उदाहरण के ऊपर सब कुछ साधारण Angular है; इसके नीचे सब कुछ संपादक है जो iframe में अपना काम कर रहा है जिसे आपको कभी भी छूने की ज़रूरत नहीं है।
  1. Angular application
  2. Editor route (lazy-loaded)
  3. EditorComponent
  4. GrapesJS instance
  5. Canvas iframe

यदि संपादक को एप्लिकेशन में कहीं और से पहुंचा जा सकता है - शेल में एक टूलबार, एक पृष्ठ सूची, एक पूर्वावलोकन फलक - एक इंजेक्टेबल सेवा में आरंभीकरण को स्थानांतरित करें और घटकों को सीधे संपादक के बजाय उस पर बात करने दें।

कैनवास एक वास्तविक iframe है। यह जानबूझकर है: पृष्ठ शैलियाँ आपके व्यवस्थापक इंटरफ़ेस में लीक नहीं हो सकती हैं और आपकी एप्लिकेशन शैलियाँ संपादित किए जा रहे पृष्ठ में लीक नहीं हो सकती हैं, जो कि बिल्कुल वही अलगाव है जो आप चाहते हैं जब दोनों अलग-अलग लोगों द्वारा डिज़ाइन किए जाते हैं।

उत्पादन

GrapesJS क्या उत्पन्न करता है?

तीन कलाकृतियाँ, और उन्हें मिलाने से वास्तविक डेटा हानि होती है। प्रोजेक्ट डेटा संपादन योग्य दस्तावेज़ है; HTML और CSS प्रकाशित परिणाम हैं। वे विनिमेय नहीं हैं, क्योंकि निर्यात डिजाइन द्वारा हानिपूर्ण है।

परियोजना डेटा

एक JSON दस्तावेज़ जिसमें घटकों, शैलियों, पृष्ठों और संपत्तियों को रखा जाता है। यह वही है जिसे आप संग्रहीत करते हैं ताकि एक संपादक पृष्ठ को ठीक उसी तरह फिर से खोल सके जैसे इसे छोड़ा गया था। इसे सत्य के स्रोत के रूप में मानें।

HTML

पृष्ठ के लिए मार्कअप के रूप में इसे परोसा जाएगा। इसे प्रोजेक्ट डेटा के साथ स्टोर करें ताकि प्रकाशन को कभी भी संपादक को बूट न करना पड़े, और इसलिए संपादक अनुपलब्ध होने पर भी एक पृष्ठ प्रस्तुत हो सकता है।

CSS

संपादक ने उस पृष्ठ के लिए जो शैलियाँ तैयार की हैं, वे उन नियमों के अनुरूप हैं जिन्हें वह प्रबंधित करता है। इसे HTML के साथ परोसें - दोनों दो फ़ाइलों में विभाजित एक आउटपुट हैं।

output.tsts
// Three outputs, three different jobs. Do not use one where you need another.

const projectData = editor.getProjectData(); // editable state → store this
const html = editor.getHtml();               // markup         → publish this
const css = editor.getCss();                 // styles         → publish this

// Reopening a saved project restores components, styles, pages and assets.
// Re-parsing exported HTML does not — it loses everything not in the markup.
editor.loadProjectData(projectData);

निर्यात किए गए HTML को वापस संपादक में बदलना प्रोजेक्ट डेटा का विकल्प नहीं है: यह घटक प्रकार, traits, पृष्ठ संरचना और कुछ भी खो देता है जो मार्कअप में व्यक्त नहीं किया जा सकता था। GrapesJS एक संपादक है, न कि CMS या बैकएंड - जहां कलाकृतियां जाती हैं, और बाद में उनके साथ क्या होता है, यह आपके आवेदन का निर्णय है।

दृढ़ता

अपने Angular एप्लिकेशन में GrapesJS प्रोजेक्ट सहेजें

GrapesJS अनुबंध को परिभाषित करता है; आप समापन बिंदु प्रदान करते हैं। दो एसिंक विधियों के साथ एक नामित भंडारण पंजीकृत करें और संपादक उन्हें कॉल करेगा - मांग पर, या स्वचालित रूप से संपादन जमा होने पर। प्रमाणीकरण, किरायेदारी और अनुमतियों के बारे में सब कुछ वहीं रहता है जहां यह है, आपकी Angular सेवाओं और आपके API में।
  1. Angular
  2. GrapesJS Storage
  3. HttpClient → REST API
  4. Your backend
  5. Database
project-storage.service.tsts
// project-storage.service.ts
import { Injectable, inject } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { firstValueFrom } from 'rxjs';
import type { Editor, ProjectData } from 'grapesjs';

@Injectable({ providedIn: 'root' })
export class ProjectStorage {
  private readonly http = inject(HttpClient);

  /** Registers a named storage the editor can then autosave into. */
  register(editor: Editor, projectId: string): void {
    editor.Storage.add('gjs-api', {
      load: () =>
        firstValueFrom(this.http.get<ProjectData>(`/api/projects/${projectId}`)),

      store: async (data) => {
        await firstValueFrom(
          this.http.put(`/api/projects/${projectId}`, {
            project: data,          // what the editor reopens
            html: editor.getHtml(), // what the site renders
            css: editor.getCss(),
          })
        );
      },
    });
  }
}
editor.component.ts (अंश)ts
// Point the editor at the storage you just registered.
this.storage.register(editor, projectId);

grapesjs.init({
  container: host,
  storageManager: {
    type: 'gjs-api',      // the name passed to Storage.add()
    autosave: true,
    autoload: true,
    stepsBeforeSave: 5,   // batch edits instead of a request per keystroke
  },
});

संपादक कभी भी आपके डेटाबेस से बात नहीं करता है। यह आपके द्वारा पंजीकृत दो विधियों को कॉल करता है, जो HttpClient को कॉल करता है, जो आपके API को उसी इंटरसेप्टर के तहत कॉल करता है और एप्लिकेशन में हर दूसरे अनुरोध के रूप में प्रमाणीकरण करता है।

दृढ़ता चेकलिस्ट

पहली बचत से पहले पांच निर्णय लेने होंगे

  1. 1
    परियोजना JSON

    संपादन योग्य दस्तावेज़ संग्रहीत करें

    उपयोगकर्ता द्वारा फिर से खोले जाने वाले रिकॉर्ड के रूप में getProjectData() आउटपुट जारी रखें। निर्यात किए गए HTML और CSS को एक ही लेखन में संग्रहीत करें ताकि प्रकाशन में कोई दूसरा दौर यात्रा न हो।

  2. 2
    स्वतः सेव

    बैच लिखता है, उन्हें स्ट्रीम न करें

    autosave stepsBeforeSave के साथ संपादनों के एक विस्फोट को एक अनुरोध में बदल देता है। Tune चरणों की गिनती आपके API में करें, डेमो डिफ़ॉल्ट के लिए नहीं।

  3. 3
    भार

    ऑटोलोड, या स्पष्ट रूप से लोड करें

    autoload संपादक को शुरू करने देता है। इसके बजाय स्पष्ट रूप से लोड हो रहा है आपको अपना खुद का स्पिनर दिखाने और संपादक के बजाय एक एप्लिकेशन त्रुटि के रूप में 403 को संभालने के लिए एक जगह देता है।

  4. 4
    संस्करणों

    इतिहास सर्वर-साइड रखें

    पूर्ववत स्टैक ब्राउज़र में रहता है और टैब के साथ मर जाता है। यदि उपयोगकर्ताओं को कल के पृष्ठ को पुनर्स्थापित करने की आवश्यकता है, तो यह आपके डेटाबेस में एक संस्करण तालिका है, जो स्टोर पर लिखी गई है।

  5. 5
    प्रकाशित करना

    प्रकाशन से अलग बचत

    सेव ड्राफ़्ट को अपडेट करता है. प्रकाशन लाइव रूट के लिए एक विशिष्ट संस्करण को बढ़ावा देता है — एक अलग समापन बिंदु, अपनी स्वयं की अनुमति जांच के साथ.

मीडिया

छवियों और संपत्तियों का प्रबंधन करें

परिसंपत्ति प्रबंधक एक पिकर है, फ़ाइल सेवा नहीं। इसे अपने Angular एप्लिकेशन में एक समापन बिंदु पर इंगित करें और यह वहां फाइलें पोस्ट करेगा; उसके बाद सब कुछ - सत्यापन, भंडारण, आकार बदलना, वितरण - लागू करना आपका है, जो आपके पास पहले से मौजूद मीडिया लाइब्रेरी का पुनः उपयोग करना संभव बनाता है।

editor.component.ts (अंश)ts
// Assets go to your endpoint, under your auth — GrapesJS only POSTs files.
grapesjs.init({
  container: host,
  assetManager: {
    upload: `/api/projects/${projectId}/assets`,
    uploadName: 'files',
    multiUpload: true,
    credentials: 'include',
    headers: { 'X-Requested-With': 'XMLHttpRequest' },
    // Off by default is the safer choice: base64 images end up inside saved
    // markup and make every page row grow without limit.
    embedAsBase64: false,
    // Returning false aborts the upload before the request leaves the browser.
    beforeUpload: (files: File[]) =>
      files.every((file) => file.size <= MAX_UPLOAD_BYTES && ALLOWED_TYPES.has(file.type)),
  },
});

editor.on('asset:upload:start', () => this.uploading.set(true));
editor.on('asset:upload:end', () => this.uploading.set(false));
editor.on('asset:upload:error', (error) => this.uploadError.set(String(error)));
  • अपलोड आपके हेडर और क्रेडेंशियल्स के साथ आपके समापन बिंदु पर जाते हैं, इसलिए बाकी ऐप के समान ही प्रमाणीकरण लागू होता है।
  • अनुरोध ब्राउज़र छोड़ने से पहले और फिर से सर्वर पर मान्य करें - क्लाइंट-साइड चेक सुविधा है, नियंत्रण नहीं।
  • अपने समापन बिंदु से संग्रहीत URL लौटाएं; संपादक उन URL को पृष्ठ में रखता है, इसलिए वे वही होने चाहिए जिन्हें आप सेवा देना चाहते हैं।
  • base64 एम्बेडिंग को तब तक बंद करें जब तक कि आप सहेजे गए मार्कअप में छवियों को इनलाइन नहीं करना चाहते हैं, जहां वे प्रत्येक संग्रहीत पृष्ठ को बिना किसी सीमा के बढ़ाते हैं।
  • CDN या ऑब्जेक्ट स्टोर से संपत्ति परोसें और संपादक को सार्वजनिक URL पर इंगित करें, न कि अपने एप्लिकेशन मूल पर।
  • संपादक को आरंभीकरण पर हजारों संपत्तियां सौंपने के बजाय एक पृष्ठांकित समापन बिंदु के माध्यम से बड़े पुस्तकालयों को लोड करें।

इनमें से कोई भी एक विशेष बैकएंड निर्धारित नहीं करता है। S3, Cloudinary, एक लारवेल डिस्क या सर्वर पर एक फ़ोल्डर सभी एक ही अनुबंध को पूरा करते हैं: एक फ़ाइल स्वीकार करें, एक यूआरएल लौटाएं।

संपादक का विस्तार

कस्टम घटक बनाएं

एक घटक प्रकार को पंजीकृत करना यह है कि संपादक आपके उत्पाद के बारे में कैसे सीखता है। एक कस्टम प्रकार को अपना स्वयं का सेटिंग पैनल, अपने स्वयं के ड्रैग-एंड-ड्रॉप नियम और पैलेट में एक ब्लॉक मिलता है - इसलिए सामग्री टीमें कच्चे divs के बजाय आपके डोमेन से अवधारणाओं के साथ काम करती हैं।

pricing-table.type.tsts
// pricing-table.type.ts — an application-specific building block.
import type { Editor } from 'grapesjs';

export function registerPricingTable(editor: Editor): void {
  editor.Components.addType('pricing-table', {
    // Lets the editor recognise the type again when a saved page is reparsed.
    isComponent: (el) => el.classList?.contains('pricing-table'),
    model: {
      defaults: {
        tagName: 'section',
        attributes: { class: 'pricing-table' },
        droppable: false,
        // Traits become the right-hand settings panel for this component.
        traits: [
          { type: 'text', name: 'plan', label: 'Plan name' },
          { type: 'number', name: 'price', label: 'Price' },
          { type: 'checkbox', name: 'featured', label: 'Highlight' },
        ],
        components: `
          <h3 data-gjs-type="text">Team</h3>
          <p data-gjs-type="text">$29 / month</p>
        `,
      },
    },
  });

  // A block is how the component reaches the user: one entry in the palette.
  editor.Blocks.add('pricing-table', {
    label: 'Pricing table',
    category: 'Commerce',
    content: { type: 'pricing-table' },
  });
}

विशिष्ट अनुप्रयोग-विशिष्ट घटक

  • Hero अनुभाग
  • मूल्य निर्धारण तालिका
  • उत्पाद कार्ड
  • फार्म
  • नेविगेशन
  • प्रशंसापत्र
  • फ़ीचर ग्रिड
  • आपके लिए कुछ भी विशिष्ट SaaS

दो चीजें एक कस्टम प्रकार को उपयोगी बनाती हैं। isComponent संपादक को आपके प्रकार को फिर से पहचानने देता है जब एक सहेजे गए पृष्ठ को फिर से पार्स किया जाता है, और traits एक गैर-तकनीकी उपयोगकर्ता वास्तव में संपादित करता है। दोनों एक साधारण घटक के लिए भी लिखने लायक हैं।

परिणाम

आप क्या बना सकते हैं?

एक ही एकीकरण इन सभी को रेखांकित करता है। उनके बीच क्या परिवर्तन होता है कि आप किन ब्लॉकों को पंजीकृत करते हैं, आप किन शैलियों को उजागर करते हैं, और आउटपुट कहां प्रकाशित होता है।

Angular पेज बिल्डर

आपके Angular एप्लिकेशन के अंदर एक दृश्य पृष्ठ संपादन अनुभव, आपके अपने ब्लॉक, आपके स्वयं के ब्रांड बाधाओं और आपके स्वयं के प्रकाशन प्रवाह के साथ।

एक पूर्ण Angular पेज बिल्डर बनाएं

Angular CMS संपादक

सामग्री टीमों को टिकट दाखिल करने के बजाय पृष्ठों को विज़ुअल रूप से संपादित करने दें। संपादक उस व्यवस्थापक एप्लिकेशन का एक मार्ग बन जाता है जिसका वे पहले से उपयोग करते हैं।

हेडलेस CMS पैटर्न देखें

Angular लैंडिंग पेज बिल्डर

पुनः प्रयोज्य विपणन अनुभाग और लेआउट, कॉपी के हर परिवर्तन के लिए तैनाती के बिना एक विपणन टीम द्वारा इकट्ठे किए गए।

लैंडिंग पेज बिल्डर पैटर्न

Angular ईमेल बिल्डर

ईमेल टेम्प्लेट को नेत्रहीन रूप से बनाएं और प्रबंधित करें, MJML प्रीसेट प्रोडक्शन मार्कअप के साथ जो वास्तविक ईमेल क्लाइंट से बचता है।

ईमेल के लिए GrapesJS

व्हाइट-लेबल विज़ुअल एडिटर

आपके SaaS उत्पाद के अंदर एक ब्रांडेड संपादक, संपादक के अपने क्रोम के साथ बदल दिया गया है ताकि यह किसी तृतीय-पक्ष टूल के बजाय आपके इंटरफ़ेस के रूप में पढ़ा जा सके।

संपादक को व्हाइट-लेबल करें

दृश्य HTML संपादक

उपयोगकर्ताओं को दृश्य संपादन दें जबकि आपका एप्लिकेशन डेटाबेस में समाप्त होने वाले HTML और CSS पर नियंत्रण रखता है।

HTML ड्रैग-एंड-ड्रॉप बिल्डर बनाना सीखें
इसे बढ़ाएं

प्लगइन्स के साथ GrapesJS बढ़ाएं

एक प्लगइन एक फ़ंक्शन है जो संपादक उदाहरण प्राप्त करता है, इसलिए यहां कुछ भी Angular-विशिष्ट नहीं है - GrapesJS के लिए प्रकाशित कुछ भी Angular घटक के अंदर काम करता है। ये चार अंतराल हैं जो संपादक माउंट के बाद पहले टीमें हिट करती हैं।

बनाएं या अपनाएं

संपादक स्वयं बनाएं या GrapesJS का उपयोग करें?

Angular में एक विज़ुअल एडिटर बनाना संभव है - यह एक ज्ञात मात्रा में काम है, असंभव नहीं। सवाल यह है कि आप उत्पाद के जीवनकाल के लिए इसके कौन से हिस्से रखना चाहते हैं।

योग्‍यताअपने आप को बनाएंGrapesJS
कैंवसनिर्माणशामिल
खींचें और छोड़ेंनिर्माणशामिल
अवयवनिर्माणशामिल
ब्लॉकनिर्माणशामिल
बिछानानिर्माणशामिल
संपत्तिनिर्माणशामिल
भंडारनिर्माणएक्स्टेंसिबल - आप समापन बिंदुओं की आपूर्ति करते हैं
प्लगइन्सएक पारिस्थितिकी तंत्र का निर्माण करेंPlugin वास्तुकला
Angular एकीकरणआपके ऐप का मूल निवासीएक घटक के माध्यम से एकीकृत करें
लाइसेंसतुम्हाराBSD-3-Clause — $0 to use

"बिल्ड" कोई आलोचना नहीं है - इनमें से हर एक निर्माण योग्य है। यह एक बयान है कि बाद में इसे कौन बनाए रखता है।
इस तालिका में तथ्यों को फिर से सत्यापित किया गया 2026-09-02।

Angular आपको एप्लिकेशन फ्रेमवर्क देता है। GrapesJS आपको विज़ुअल एडिटिंग इंजन देता है।

एकीकरण विकल्प

क्या मुझे Angular के लिए GrapesJS रैपर की आवश्यकता है?

नहीं, और यह समझने योग्य है कि सवाल क्यों आता है। GrapesJS एक आधिकारिक React रैपर प्रकाशित करता है, इसलिए डेवलपर्स यथोचित रूप से Angular समकक्ष की उम्मीद करते हैं। एक नहीं है। यह तीन दृष्टिकोण छोड़ देता है, और अधिकांश टीमों के लिए पहला सही उत्तर है।

अधिक:

प्रत्यक्ष एकीकरण

घटक को स्वयं लिखें - इस पृष्ठ पर एक लगभग तीस पंक्तियों का है। आप जीवनचक्र, परिवर्तन-पहचान रणनीति और अपग्रेड पथ के मालिक हैं, और आपके ऐप और संपादक API के बीच कोई तीसरा पक्ष नहीं है।

  • Angular रिलीज़ के साथ वर्तमान रखने के लिए कोई अतिरिक्त निर्भरता नहीं
  • प्रत्येक संपादक विकल्प और घटना तक पूर्ण पहुंच
  • तुरंत GrapesJS भूमि में अपग्रेड
तृतीय-पक्ष

एक सामुदायिक आवरण

सामुदायिक पैकेज मौजूद हैं और पहले घंटे को छोटा कर सकते हैं। किसी भी निर्भरता का मूल्यांकन करें: जांचें कि इसे कौन बनाए रखता है, कौन से Angular और GrapesJS संस्करण घोषित करता है, और यह हाल ही में कैसे प्रकाशित हुआ था।

  • GrapesJS परियोजना द्वारा बनाए नहीं रखा गया
  • Angular और GrapesJS दोनों पर एक संस्करण बाधा जोड़ता है
  • अपनाने से पहले वर्तमान कोर रिलीज के खिलाफ जांच करने लायक
  • ngx-grapesjs 21.0.0 · 2026-01-15 · peer grapesjs ^0.22.4
बड़े ऐप्स के लिए

आपका अपना सर्विस रैपर

एक बार जब कई घटकों को संपादक की आवश्यकता होती है - एक टूलबार, एक पृष्ठ सूची, एक पूर्वावलोकन फलक - आरंभीकरण को एक इंजेक्शन सेवा में ले जाते हैं। यह एक सीम के साथ सीधा एकीकरण है, और यह संपादक को आपके घटक वृक्ष से बाहर रखता है।

  • एक जगह जो init और नष्ट करने का मालिक है
  • Editor स्थिति संकेतों या वेधशालाओं के रूप में घटकों तक पहुंचती है
  • संपादक को माउंट किए बिना परीक्षण योग्य

GrapesJS संगठन एक React आवरण और कोई Angular पैकेज नहीं रखता है। आपको मिलने वाली कोई भी Angular लाइब्रेरी तृतीय-पक्ष है, चाहे वह कितनी भी उपयोगी क्यों न हो - इसे एक निर्भरता विकल्प के रूप में मानें, न कि GrapesJS के हिस्से के रूप में।

स्‍थापत्‍यशैली

GrapesJS + Angular के लिए उत्पादन वास्तुकला

एक डेमो एक घटक है। एक उत्पाद चार परतों का होता है, और संपादक उनमें से केवल एक होता है। यह वह आकार है जिस पर अधिकांश टीमें एक बार संपादक के पीछे वास्तविक उपयोगकर्ता होने के बाद अभिसरण करती हैं।

  1. Angular आवेदन

    शेल, राउटर, और एक आलसी-लोड किया गया मार्ग जो संपादक का मालिक है।

    • ऐप शेल
    • राउटर
    • संपादक मार्ग (आलसी)
  2. GrapesJS उदाहरण

    एक बार कॉन्फ़िगर किया गया, आरंभीकरण पर: कौन से घटक मौजूद हैं, क्या खींचा जा सकता है, क्या स्टाइल किया जा सकता है।

    • अवयव
    • ब्लॉक
    • शैलियों
    • संपत्ति
    • आदेश
  3. आवेदन सेवाएं

    संपादक और आपके Angular के बीच API परत - और एकमात्र स्थान प्राधिकरण निर्णय क्लाइंट-साइड किए जाते हैं।

    • प्रमाणीकरण
    • API ग्राहक
    • अनुमतियां
    • प्रकाशन-व्‍यवसाय
  4. बैकएंड

    कलाकृतियां कहां रहती हैं, और जहां हर अनुमति वास्तविक रूप से लागू की जाती है।

    • परियोजनाओं
    • संपत्ति
    • उपयोगकर्ता
    • संस्करणों

इस आरेख में दूसरे स्तर को छोड़कर कुछ भी GrapesJS-विशिष्ट नहीं है। यही बात है: संपादक एक साधारण Angular एप्लिकेशन में एक घटक है, और बाकी वह आर्किटेक्चर है जिसे आपने वैसे भी बनाया होगा।

देखें कि टीमें इसे उत्पाद के रूप में कैसे पैकेज करती हैं
प्रदर्शन

प्रदर्शन के विचार

संपादक आपके एप्लिकेशन के अंदर चलने वाले सॉफ़्टवेयर का एक बड़ा टुकड़ा है। ये वे स्थान हैं जहां वास्तव में कुछ खर्च होता है।

जरूरत पड़ने पर ही इनिशियलाइज़ करें

संपादन मार्ग खुलने पर संपादक बनाएं, एप्लिकेशन प्रारंभ में नहीं। जो उपयोगकर्ता कभी संपादन नहीं करते हैं उन्हें इसके लिए कभी भुगतान नहीं करना चाहिए।

मार्ग को आलसी-लोड करें

एक गतिशील आयात GrapesJS को प्रारंभिक बंडल से बाहर रखता है, जो इस सूची में सबसे बड़ा लीवर है।

क्षेत्र से बाहर रहें

runOutsideAngular के साथ संपादक बनाएं ताकि कैनवास पॉइंटर ईवेंट हर फ्रेम पर परिवर्तन का पता लगाने को ट्रिगर न करें।

एसेट लाइब्रेरी को बाउंड करें

संपादक को init पर एक पूर्ण मीडिया लाइब्रेरी न सौंपें। अपने API के माध्यम से पेगिनेट करें और पिकर के अनुरोध के अनुसार संपत्ति लोड करें।

घटक वृक्ष देखें

बहुत गहरी या बहुत दोहराव वाली पृष्ठ संरचनाएं चयन, स्टाइल और पूर्ववत धीमी गति से बनाती हैं। गहरे नेस्टेड रैपर पर घटकों को प्राथमिकता दें।

बैच बचाता है

stepsBeforeSave का उपयोग करें ताकि संपादनों का एक विस्फोट प्रति कीस्ट्रोक अनुरोध के बजाय एक अनुरोध बन जाए।

इनमें से कोई भी वादा की गई संख्या के साथ नहीं आता है। पहले और बाद में अपने स्वयं के संपादक मार्ग को मापें - प्रत्येक प्रभाव का आकार आपके ब्लॉक, आपके पृष्ठों और आपके API पर निर्भर करता है।

प्रतिभूति

सुरक्षा के मनन

एक विज़ुअल एडिटर उपयोगकर्ताओं को HTML के लेखकों में बदल देता है जो आपका एप्लिकेशन तब कार्य करता है। संपादक से निकलने वाली हर चीज को उपयोगकर्ता इनपुट के रूप में मानें, क्योंकि यह वही है जो यह है।

स्वच्छता प्रकाशित HTML

Editor आउटपुट में मनमाना मार्कअप हो सकता है, जिसमें स्क्रिप्ट भी शामिल है यदि कस्टम कोड ब्लॉक सक्षम हैं। सर्वर-साइड को उसके लेखक के अलावा किसी और को परोसने से पहले सैनिटाइज करें।

अपलोड की गई एसेट की पुष्टि करें

सर्वर पर प्रकार और आकार की जाँच करें, न कि केवल beforeUpload में। अपलोड को वेब रूट के बाहर स्टोर करें और उन्हें एक अलग मूल से परोसें।

भंडारण समापन बिंदुओं को प्रमाणित करें

लोड और सेव मार्ग साधारण API समापन बिंदु हैं। उन्हें एप्लिकेशन में बाकी सभी चीज़ों की तरह ही प्रमाणीकरण की आवश्यकता होती है।

अनुमतियाँ सर्वर-साइड लागू करें

Angular UI में एक प्रकाशन बटन छिपाना प्रस्तुति है। जो चेक मायने रखता है वह समापन बिंदु पर है।

प्रोजेक्ट डेटा पर कभी भरोसा न करें

संग्रहीत प्रोजेक्ट JSON के साथ छेड़छाड़ की जा सकती है। यह मानने के बजाय इसे लोड पर मान्य करें कि यह आपके द्वारा लिखा गया दस्तावेज़ है।

स्कोप किरायेदारों को स्पष्ट रूप से

एक बहु-किरायेदार उत्पाद में, सर्वर पर सत्र से प्रोजेक्ट के स्वामी को प्राप्त करें - अनुरोध निकाय में कभी भी आईडी से नहीं।

जहाज भेजने से पहले

Angular + GrapesJS उत्पादन चेकलिस्ट

बारह चीजें जो एक मार्ग से एक कार्यशील डेमो को अलग करती हैं, वास्तविक उपयोगकर्ताओं को दी जा सकती हैं।

  1. GrapesJS स्थापित करें

    निर्भरता जोड़ी गई और स्टाइलशीट पंजीकृत, विश्व स्तर पर या संपादक घटक में।

    अनुभाग पढ़ें
  2. दृश्य निर्माण के बाद प्रारंभ करें

    grapesjs.init() ngAfterViewInit में चलता है, एक हल की गई ऊंचाई वाले कंटेनर के खिलाफ।

    अनुभाग पढ़ें
  3. संपादक को सही ढंग से नष्ट करें

    editor.destroy() में ngOnDestroy, बिना लीक के दूर और वापस नेविगेट करके सत्यापित किया जाता है।

    अनुभाग पढ़ें
  4. केवल ब्राउज़र आरंभीकरण को संभालें

    संरक्षित इसलिए सर्वर रेंडर के दौरान कुछ भी नहीं चलता है, इसके स्थान पर एक प्लेसहोल्डर होता है।

    अनुभाग पढ़ें
  5. स्टोरेज कनेक्ट करें

    एक नामित भंडारण पंजीकृत, autosave ट्यून किया गया, और प्रोजेक्ट JSON HTML और CSS के साथ संग्रहीत किया गया।

    अनुभाग पढ़ें
  6. एसेट कॉन्फ़िगर करें

    अपलोड आपके समापन बिंदु पर इंगित किया गया है, base64 एम्बेडिंग बंद, दोनों तरफ सत्यापन।

    अनुभाग पढ़ें
  7. कस्टम घटक जोड़ें

    आपके उत्पाद के अपने बिल्डिंग ब्लॉक्स traits और पैलेट प्रविष्टियों के साथ प्रकारों के रूप में पंजीकृत हैं।

    अनुभाग पढ़ें
  8. अपनी ज़रूरत के प्लगइन्स जोड़ें

    Blocks, समृद्ध पाठ और निर्यात को संचित करने के बजाय जानबूझकर चुना गया।

    अनुभाग पढ़ें
  9. अनुमतियाँ लागू करें

    कौन संपादित कर सकता है, कौन प्रकाशित कर सकता है - सर्वर पर लागू, UI में परिलक्षित होता है।

    अनुभाग पढ़ें
  10. प्रकाशित सामग्री को सैनिटाइज़ करें

    किसी पृष्ठ को सहेजने और आगंतुकों को सेवा देने के बीच सर्वर-साइड सैनिटाइजेशन।

    अनुभाग पढ़ें
  11. मॉनिटर संपादक त्रुटियाँ

    Editor अपवादों को आपकी बाकी Angular त्रुटियों के समान स्थान पर रिपोर्ट किया गया है।

  12. उत्तरदायी संपादन का परीक्षण करें

    डिवाइस मैनेजर ने न केवल डेस्कटॉप ब्राउज़र विंडो में बल्कि टच डिवाइस पर व्यायाम किया।

    अनुभाग पढ़ें
FAQ

GrapesJS और Angular: सामान्य प्रश्न

अगला कदम

Angular के साथ अपना GrapesJS विज़ुअल एडिटर बनाएं

ओपन-सोर्स विज़ुअल एडिटर से शुरुआत करें, इसे अपने Angular एप्लिकेशन से कनेक्ट करें, और इसे प्लगइन्स और अपने उत्पाद की ज़रूरत के एकीकरण के साथ विस्तारित करें।

डेवलपर

शुरू हो जाओ

पैकेज स्थापित करें, घटक की प्रतिलिपि बनाएँ, और आज दोपहर Angular मार्ग पर एक संपादक चलाएँ।

शुरू हो जाओ
विस्तार

प्लगइन्स ब्राउज़ करें

ब्लॉक, भंडारण, समृद्ध पाठ, संपत्ति, निर्यात और ईमेल - वे टुकड़े जिन्हें आप अन्यथा स्वयं लिख रहे होंगे।

प्लगइन्स ब्राउज़ करें
टीम

उत्पाद की योजना बनाएं

संपादक को अपने एप्लिकेशन की एक विशेषता के रूप में स्कोप करें: भूमिकाएं, टेम्पलेट, प्रकाशन और संस्करण।

एक संक्षिप्त प्रारंभ करें

Angular के साथ एप्लिकेशन बनाएं। GrapesJS के साथ विज़ुअल एडिटर बनाएं। इसे GJS.Market प्लगइन्स के साथ विस्तारित करें।