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

Templates injected via JavaScript are not hydrated #502

Open
peacememories opened this issue Jan 11, 2023 · 5 comments
Open

Templates injected via JavaScript are not hydrated #502

peacememories opened this issue Jan 11, 2023 · 5 comments

Comments

@peacememories
Copy link

In our Django application, a lot of the content is rendered on the server via a template and then injected into a part of the page via JavaScript. This poses a problem when trying to add Unicorn to the codebase, since Unicorn components included in those templates are rendered correctly, but do not become interactive.

Is there a way to tell Unicorn to rescan the page for unicorn:click actions and the like after html has been added to the page by JavaScript?

@peacememories
Copy link
Author

If I manually run the code injected as a script by unicorn from the browser console, the component properly initializes. I'm not sure why this does not happen automatically O.o

@peacememories
Copy link
Author

peacememories commented Jan 11, 2023

Okay, this actually makes sense. When <script> tags are added to a page via javascript, the scripts don't automatically get called. I instead created a workaround that listens to new unicorn components being added and initializes them:

const unicornObserver = new MutationObserver((mutations) => {
    mutations.forEach(mutation => {
        mutation.addedNodes.forEach(node => {
            if(node instanceof HTMLScriptElement) {
                if(node.type === "application/json" && node.id.startsWith("unicorn:data:")) {
                    Unicorn.componentInit(JSON.parse(node.textContent))
                }
            }
        })
    })
})

unicornObserver.observe(document.body, {
    subtree: true,
    childList: true
})

Do you see any obvious problems that will bite me later with this approach? Or do you think this could be better integrated into Unicorn directly?

@peacememories
Copy link
Author

Side note: the Unicorn code is incredibly readable for newcomers trying to fix problems. Props for that :)

@adamghill
Copy link
Owner

That's awesome to hear. :) I don't see anything in your approach that worries me.

It does seem like something that could be integrated into Unicorn itself. If you are able to make a PR that would awesome. Otherwise I can probably work on this in the next couple of days I think. I know there are others who would benefit from this functionality. 👍

@peacememories
Copy link
Author

peacememories commented Jan 17, 2023

For now, the decision in our company was to not adopt Unicorn, so I am not going to have much time to integrate this. Also, this seems like a much more heavy-handed approach to initializing new components than the current one. Maybe it could be added as a setting.

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

2 participants