[Feature]: Clone a page #5448
Replies: 3 comments
-
Moved to Roadmap Suggestions |
Beta Was this translation helpful? Give feedback.
-
Huge +1 for this feature request! A native page cloning ability is definitely needed. For anyone else looking for a solution until then, here's an approach I've put together that's working well for me. The core idea is to use the system clipboard to temporarily store the ID of the page being copied. The "paste" action then reads this ID, creates a new blank page, and finally populates it by cloning the components from the source page. Here’s a breakdown of the implementation, which is written within a React/TypeScript context ( The Copy ActionInstead of serializing the entire page object, the copy function just grabs the ID of the selected page and writes it to the clipboard. This is lightweight and avoids managing a large data object. const onCopy = () => {
// Assuming 'selected' is the currently selected page object from GrapesJS PageManager
const pageId = selected ? selected.getId() : '';
if (pageId) {
navigator.clipboard.writeText(pageId);
}
}; The Paste ActionThe paste logic is a two-step process: first, create the new page "shell," and second, copy the content over. 1. Create the New Page The const onPaste = async () => {
const sourcePageId = await navigator.clipboard.readText();
const pageManager = editor.Pages;
const sourcePage = pageManager.get(sourcePageId);
if (!sourcePage) {
console.error(`Page not found for ID: ${sourcePageId}`);
return;
}
// Generate a unique ID for the new page
const newPageId = `page-${uuidv4()}`;
pageManager.add({
id: newPageId,
name: `Copy of ${sourcePage.getName()}`,
// Optional: for nested pages
// parentId: selected?.getId(),
});
// Now, copy the content from the source page to the new one
copyPageContent(sourcePageId, newPageId);
}; 2. Copy the Page Content Key Steps:
const copyPageContent = (fromPageId, toPageId) => {
const sourcePage = editor.Pages.get(fromPageId);
const targetPage = editor.Pages.get(toPageId);
if (!sourcePage || !targetPage) return;
// IMPORTANT: Select the target page before adding components to it.
editor.Pages.select(targetPage);
const sourceComponents = sourcePage.getMainComponent().components();
for (const component of sourceComponents) {
// Optional: Skip specific components that shouldn't be duplicated (e.g., global headers/footers).
if (component.is('your-custom-component-type-to-skip')) {
continue;
}
// Clone the component and add it to the new page's body.
const clonedComponent = component.clone();
editor.addComponents(clonedComponent);
}
}; I'm open to any feedback on this implementation, especially if there are potential edge cases or performance issues I might have missed |
Beta Was this translation helpful? Give feedback.
-
We don't have a direct method for page cloning but you can do this with the current API const selectedPage = editor.Pages.getSelected();
editor.Pages.add({
name: `${selectedPage.getName()} (Copy)`,
component: selectedPage.getMainComponent().clone(),
}, { select: true }); |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
Clone a predefined page just with page ID. Create a new method under https://grapesjs.com/docs/api/pages.html#pages for cloning a page.
const pageId = pageManager.get('page-id'); pageManager.clone(pageId);
Beta Was this translation helpful? Give feedback.
All reactions