When using jQuery and loading JS pack from the <head> Bootstrap 5 throws an error:

The offending line:
should check for the presence of body.
Docs do not state that JS bundle needs to be in the body so I conclude this is a bug. Happy to submit a PR if confirmed.
Demo site:
https://amazing-heisenberg-e74368.netlify.app/ (see console)
Can you try to load the JS at the end of the body ?
That's what we recommend here: https://v5.getbootstrap.com/docs/5.0/getting-started/introduction/#js
@jacklimo As @Johann-S says the JS needs to be loaded in the footer.
I had exactly the same error and after moving the JS to the footer is cleared. I assume that it was not a problem in V4 simply because the check was not there.
A slight update to the docs might be helpful to explain that the check is there, and what it is doing.
@Johann-S @chrisdavies71 while moving the script to the body certainly works, it introduces a limitation. I can see associated costs but not many benefits, so I'd like to discuss if that limitation is justified.
To give some background, I'm working with a Rails app using Turbolinks, JS bundles are optimized for caching and placed in head. This works without issues in v4.
To make this work with v5, I can't move everything into body (Turbolinks need to stay in head), so I'll need a separate bundle. This isn't always a trivial task.
So it looks to me like we're trading the flexibility of being able to load JS code from anywhere for the abillity to read an attribute from the body. Is there anything else on the roadmap that depends on the JS code being run from the body that would make a stronger case for strict placement inside of body?
Perhaps we could maintain the flexibility if:
a) reading data-no-jquery attribute doesn't throw an error when executed from the head
b) just like jQuery is found on the window object, we could look for a flag property on the window object to opt out of jQuery plugins (e.g. window.bsNoJquery), rather than looking for that flag on the body
BTW this suggestion was present in v4 too: https://getbootstrap.com/docs/4.5/getting-started/introduction/#js
I'm not against checking if the body element is present 馃憤
I prefer to stick with data attribute to disable jQuery on demand, it's easier to edit some HTML compared to adding JavaScript.
I agree with you @Johann-S data attributes are more conventional throughout the codebase 馃憤
I think it makes sense that users placing the bundle in the head implicitly opt out of depending on the value of the attribute on the body so we can only check it when executed from within body.
I'll take a shot at a PR.
Wouldn't adding a DOMContentLoaded event take care of this? It shouldn't matter then where JS is.
it's not that easy, getJQuery is called in each of our components, so if we must add a DOMContentLoaded in each of our plugins, it's a lot of code 馃槦
Hmm, true. But the current situation isn't ideal either :/ We should try with DOMContentLoaded and see how much it adds, it shouldn't be that much for our bundle files.
I also hope to see a solution for this. For now I load bootstrap JS from version 4 and css from version 5. But that's super temporary not recommended "solutions"...
Patches are always welcome :)
That being said, I wonder if we can add a new utility function and call that in all of the plugins?
Interesting idea. But if would wait for DOMContentLoaded, then it's "difficult" to use a utility function. This utility function needs a callback then, to execute const $ = getjQuery() and the jquery extension part as soon as the dom is loaded.
Question in general: Why is the flag "data-no-jquery" needed at all? Isn't it an expected behaviour, that jQuery will be extended, if I use jquery in my project?
The change was made in #29191. At this point I'd say we maybe just get a way with reverting that PR. I don't recall more details and the PR does not link to another issue.
Otherwise if someone could make a PR using DOMContentLoaded, that would help.
Most helpful comment
@Johann-S @chrisdavies71 while moving the script to the body certainly works, it introduces a limitation. I can see associated costs but not many benefits, so I'd like to discuss if that limitation is justified.
To give some background, I'm working with a Rails app using Turbolinks, JS bundles are optimized for caching and placed in
head. This works without issues in v4.To make this work with v5, I can't move everything into
body(Turbolinks need to stay in head), so I'll need a separate bundle. This isn't always a trivial task.So it looks to me like we're trading the flexibility of being able to load JS code from anywhere for the abillity to read an attribute from the
body. Is there anything else on the roadmap that depends on the JS code being run from thebodythat would make a stronger case for strict placement inside ofbody?Perhaps we could maintain the flexibility if:
a) reading
data-no-jqueryattribute doesn't throw an error when executed from theheadb) just like
jQueryis found on thewindowobject, we could look for a flag property on thewindowobject to opt out ofjQueryplugins (e.g.window.bsNoJquery), rather than looking for that flag on thebody