Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BUG: HTML elements ids are incremented on different pages loaded in projectData #4837

Open
2 tasks done
quentin-bettoum opened this issue Jan 10, 2023 · 8 comments
Open
2 tasks done

Comments

@quentin-bettoum
Copy link
Contributor

GrapesJS version

  • I confirm to use the latest version of GrapesJS

What browser are you using?

Firefox 109

Reproducible demo link

https://grapesjs.com/demo.html

Describe the bug

Hello,

I noticed that when I load multiple pages in the projectData that have the same id used in the HTML, grapes will automatically increment the id on every page even though these are different pages.

To demonstrate this issue, you will find a piece of code below where I init grapesjs with a projectData containing two pages using identical ids on some HTML tags.

On the resulting HTML list, you can see the ids like body and main-title are incremented to body-2 and main-title-2 on the second page.

const editortest = grapesjs.init({
  headless: true,
  projectData: {
    pages: [
      {
        "frames": [
          {
            "component": {
              "type": "wrapper",
              "stylable": [
                "background",
                "background-color",
                "background-image",
                "background-repeat",
                "background-attachment",
                "background-position",
                "background-size"
              ],
              "attributes": {
                "id": "body"
              },
              "components": [
                {
                  "tagName": "section",
                  "components": [
                    {
                      "tagName": "h1",
                      "type": "text",
                      "attributes": {
                        "id": "main-title"
                      },
                      "components": [
                        {
                          "type": "textnode",
                          "content": "This is a simple title"
                        }
                      ]
                    },
                    {
                      "type": "text",
                      "components": [
                        {
                          "type": "textnode",
                          "content": "This is just a Lorem text: Lorem ipsum dolor sit amet"
                        }
                      ]
                    }
                  ]
                }
              ]
            }
          }
        ],
        "id": "ljc0blhC1ZeiCYyY"
      },
      {
        "frames": [
          {
            "component": {
              "type": "wrapper",
              "stylable": [
                "background",
                "background-color",
                "background-image",
                "background-repeat",
                "background-attachment",
                "background-position",
                "background-size"
              ],
              "attributes": {
                "id": "body"
              },
              "components": [
                {
                  "tagName": "section",
                  "components": [
                    {
                      "tagName": "h1",
                      "type": "text",
                      "attributes": {
                        "id": "main-title"
                      },
                      "components": [
                        {
                          "type": "textnode",
                          "content": "This is another title"
                        }
                      ]
                    },
                    {
                      "type": "text",
                      "components": [
                        {
                          "type": "textnode",
                          "content": "Some other text"
                        }
                      ]
                    }
                  ]
                }
              ]
            }
          }
        ],
        "id": "1zKkQnGVzy8nKXKE"
      }
    ]
  }
})

let pages = editortest.Pages.getAll().map(page => {
  const component = page.getMainComponent();
  return editortest.getHtml({ component })
});

console.log(pages)

The pages result:

[
  "<body id=\"body\"><section><h1 id=\"main-title\">This is a simple title</h1><div>This is just a Lorem text: Lorem ipsum dolor sit amet</div></section></body>",
  "<body id=\"body-2\"><section><h1 id=\"main-title-2\">This is another title</h1><div>Some other text</div></section></body>"
]

Code of Conduct

  • I agree to follow this project's Code of Conduct
@artf
Copy link
Member

artf commented Jan 18, 2023

Even with multiple pages all components have to maintain a unique id across whole project.
I'd not expect the editor to output this so I'm wondering if you edited the JSON on purpose or you have reproducible steps to have this outcome?

@quentin-bettoum
Copy link
Contributor Author

My use case might explain how I had this result.

I am building a CMS using GrapesJS as a Page Builder.
To create each page, I chose to load Grapes in "single page mode", if that makes sense. This is to avoid sending too much data to the client on a project containing a lot of pages.
Then, to generate the final website, the goal is to load Grapes in headless mode serverside (using NodeJS) to merge all the pages and styles.

I can live without ids at the moment, this is just something I noticed in my multiple tries.
In the long term, maybe it could make sense for Grapes to use some data attributes (something like data-grapes-id) as unique identifiers to leave the id free for some frontend scripts.

I might open a discussion where we could speak more about this CMS I'm building. I'd be glad to have your opinions and advices on my design choices.

@artf
Copy link
Member

artf commented Jan 27, 2023

Then, to generate the final website, the goal is to load Grapes in headless mode serverside (using NodeJS) to merge all the pages and styles.

I'm wondering if it would make sense to you generating each page separately

@quentin-bettoum
Copy link
Contributor Author

At first, I wanted to generate all the pages together to have a single CSS output for all the pages. But now I'm trying another solution for the styles.

So for the id problem, generating each page separately could be a solution. Thanks for the idea.

@vizardkill
Copy link

I have a question regarding the StoreManager, if users start creating many pages, at what point does performance start to be lost? , taking into account that you must store the assets, and the styles and taking into account how you could store this information in a database without affecting the load of the API when processing so much information

@lexoyo
Copy link
Contributor

lexoyo commented Apr 24, 2023

Hello
In Silex v3 I encounter this bug too and I have a use case for which it is a real issue unfortunately
We have a menu using a checkbox and a label to open/close it so we need to have an id on the checkbox (used in the for attribute of the label)
We use symbols to have the menu on all pages so it has to be the same id...

@bgrand-ch
Copy link
Contributor

Grapes to use some data attributes (something like data-grapes-id) as unique identifiers to leave the id free for some frontend scripts.

I like this idea 💯

@elfalem
Copy link

elfalem commented Aug 7, 2024

I also have a use case where the content is initially generated outside of the editor so different pages can have elements with the same id.

Even with multiple pages all components have to maintain a unique id across whole project.

Is it possible to relax this constraint so that ids are namespaced by pages?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants