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

CSS file doesn't load on page transition #410

Open
Damiano31 opened this issue Jun 19, 2019 · 32 comments
Open

CSS file doesn't load on page transition #410

Damiano31 opened this issue Jun 19, 2019 · 32 comments

Comments

@Damiano31
Copy link

Hi, I have a problem with the css and js files. I would like to use different style sheets and scripts on the various pages. when I open the page everything normally works, but when I change the page using the transition it is not loaded. How can I solve it?

for example
in the contact page i want to use contact.css. contact.css is used only in this page. when I access the page directly the css works correctly but when i came from (for example) index.html that doesn't have contatti.css the style doesn't load.

@codymx
Copy link

codymx commented Jun 19, 2019

As far as I'm aware, everything will need to be loaded outside of the container. Combine your CSS files into one and it'll work fine. In my opinion, this is only adding more http requests every time the user goes to another page, increasing the load time.

As for JS, it won't be re-evaluated when a transition completes, so it too will have to be compiled and loaded outside of the container. You'll have to reinitialize any functions using barba hooks.

On barba v1:

Barba.Dispatcher.on('newPageReady', function(currentStatus, oldStatus, container) {
  // JS functions here
});

on barba v2:

barba.hooks.afterEnter( ( data ) => {
  // JS functions here
} );

@xavierfoucrier
Copy link
Member

I agree with @c0mrx,

Just one file for CSS and another one for JS = no more https requests when you switch between pages.

Anyway, this is a feature that will be implemented soon in the v2, called @barba/head, allowing Barba to automatically fetch head files that are not in the cache, mostly scripts and stylesheets.

😉

@stale stale bot added the wontfix label Oct 1, 2019
@xavierfoucrier xavierfoucrier changed the title css file doesn't load on page transition CSS file doesn't load on page transition Oct 6, 2019
@Geestig
Copy link

Geestig commented Oct 10, 2019

Any update about the @barba/head addition?

I have a similar issue.

I have some 'detail' pages that get some inline styles injected. The styles get inject in the head and are specific for each 'detail' page. So it should reload the head on every 'detail' page.

@xavierfoucrier
Copy link
Member

Hi @Geestig,

Still a feature to implement into the library, but no roadmap specified for the moment.

Thanks for using Barba and for your patience 😉

@Geestig
Copy link

Geestig commented Oct 10, 2019

Do you happen to have a temporary solution/idea for my issue?

I was thinking on using the beforeEnter hook to check the incoming HTML for the style tag en inject it into the head of the page. And remove it afterwards with the afterLeave hook.

@xavierfoucrier
Copy link
Member

xavierfoucrier commented Oct 10, 2019

Using the beforeEnter hook to inject styles using <link> into the <head> seems to be the appropriate solution 👍

Be sure to properly remove the styles on the afterLeave hook and it will work just fine 👍

For a complete example, see: #485 (comment)

@xavierfoucrier xavierfoucrier added the hacktoberfest Hacktoberfest® event - https://hacktoberfest.digitalocean.com label Oct 22, 2019
@WebMechanic
Copy link

I was thinking on using the beforeEnter hook to check the incoming HTML for the style tag en inject it into the head of the page. And remove it afterwards with the afterLeave hook.

@Geestig there's no need,technically or otherwise, to make things more complicated and parse out <style> or <link> elements to move them or their contents to the <head>. Generally speaking: CSS within style/link elements anywhere on the page is not scoped but follows the cascade and whatever @media rules within it apply even if added after the fact (page load).
If you include CSS (snippets) to the incoming HTML to only format that additional content it'll be automatically enabled by the browser for the whole rendered page; remove the HTML and style elements/CSS and all is gone. Using ids to easy select these element will simplify your code.

Since you already fetch additional files from the server, using sth. like

<style>@import "page-foo.css"</style>
<style>.bar {color:fuchsia}</style>
... the remaining HTML for that page ...

or

<link rel="stylesheet" href="page-foo.css" media="all" >
... the remaining HTML for that page ...

None of this would bring down the page (nor server), yet @import just like <link> -- in this case -- will be cached and allows you to use and reuse external .css chunks on various "pages". If you prefer CSS code inline, you're also good to go, but loose caching.
You're unlikely to experience FOUC with this approach.

Don't be too religious about minimizing HTTP requests :)
Your server probably runs with http2 anyways.

Enjoy.

@Geestig
Copy link

Geestig commented Dec 12, 2019

@WebMechanic thanks for the reply, but it was a style that was added upon load automatically. I solved it by simply filtering it out of the head and adding it to the currect active head as @xavierfoucrier had suggested.

@stale
Copy link

stale bot commented Feb 23, 2020

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@stale stale bot added the wontfix label Feb 23, 2020
@xavierfoucrier xavierfoucrier removed hacktoberfest Hacktoberfest® event - https://hacktoberfest.digitalocean.com wontfix labels Feb 23, 2020
@barbajs barbajs deleted a comment from saadkhaan Jun 12, 2020
@ouun
Copy link

ouun commented Nov 24, 2020

Hi there,
just wondering if @barba/head is still planned? Barba.js is amazing but fight with and loading additional scripts & styles is a hughe hassle. Would be amazing to get that "official" solution.

@xavierfoucrier
Copy link
Member

Hi @ouun,

It steel planned of course, but not in the next few months, sorry.
For now, you should use a workaround to properly manage styles inside your head.

Thanks for your interest into Barba 😉

@outdatedx

This comment has been minimized.

@xavierfoucrier
Copy link
Member

Hi @OutdatedDesigns,

Please use the Slack workspace in order to ask the whole community for support. Join using the invite link here: https://barba.js.org/docs/getstarted/useful-links/#Developer.

Thanks! 😉

@mudlabs

This comment was marked as off-topic.

@xavierfoucrier
Copy link
Member

Hi @mudlabs,

This if off-topic here 😉

And no, this is not a problem for SEO to not have head title and meta tags updated with the current page, see https://barba.js.org/faq/#What-about-SEO-concerns.

@evankford
Copy link

A solution I came up with for my needs here:

I had a problem with web components (custom HTML elements) not initializing when their script tags were in the barba-container. Here's what worked:

barba.init({
    ...whatever settings you have,
    transitions:[{
       name: : "your-transition-name",
       
       beforeEnter(data) {
           const nextEl = data.next.container;
           if (nextEl) { //Just a little check to make sure we don't run this on an error
               // Find all scripts in the next container
               const nextScripts = nextEl.querySelectorAll('script');
    
               //Iterate over incoming script tags
               nextScripts.forEach(nextScript => {
                  const src = nextScript.src;
                  //Duplicate check - no need to re-execute scripts that are already loaded.
                  if (document.head.querySelector('script[src="' + src + '"]') == undefined) {

                    //Have to create a new script element in order for the browser to execute the code
                    const newScript = document.createElement('script');
                    newScript.src = src;
                    newScript.async = true; 
                    document.head.append(newScript);

                    nextScript.remove(); // Cleaning up the script in the container;
                  }
           }
       },
       (...whatever other transition functions you need, like after(), once(), etc.)



});

I'm pretty sure this solves the primary problem of the script not being executed, by creating a new script tag in the header for each script tag being loaded in the body. (It seems as if the body HTML is being loaded in such a way that re-executing scripts doesn't happen, which is normal for AJAX replacement).

Some thoughts:

  • This obviously doesn't help with inline scripts, but it could easily be modified to create new script tags with the content of inline scripts from the barba-container.
  • I don't see any reason to remove scripts which were injected in previous barba lifecycles, is there a good reason to do this?
  • I also didn't have any need to reload <link> elements in the head, they seem to execute just fine from the incoming barba container.
  • What else is needed for @barba/head? Meta Tags are probably the biggest other tag to iterate over, and then probably JSON metadata.

@stepanjakl
Copy link

Hi guys, I needed to load inline scripts on each Barba transition. Inspired by @evankford, I came up with the solution below. Also related to #485.

window.Barba.currentInlineScripts = []
window.Barba.init({
    transitions: [{
        sync: false,
        afterLeave({
            current,
            next
        }) {
            if (next.container) {
                // Remove old scripts appended to the head
                window.Barba.currentInlineScripts.forEach((currentInlineScript) => {
                    currentInlineScript.remove()
                })

                // Find all new scripts in the next container
                const nextScripts = next.container.querySelectorAll('script');

                // Iterate over new scripts
                nextScripts.forEach((script) => {
                    // Check if it is an inline script
                    if (!script.src) {
                        // Clone the original script
                        const newScript = script.cloneNode(true)
                        // Create a new <script> element node
                        const newNode = document.createElement('script');
                        // Assign it innerHTML content
                        newNode.innerHTML = newScript.innerHTML
                        // Append to the <head>
                        const element = document.head.appendChild(newNode)
                        // Save for later
                        window.Barba.currentInlineScripts.push(newNode)
                    }
                    // Remove the inline script
                    script.remove()
                })
            }
        }
    }]
})

I hope it helps. Any progress on the @barba/head plugin by the way?

@carlaiau
Copy link

carlaiau commented Jun 1, 2022

I hope it helps. Any progress on the @barba/head plugin by the way?

Bumping this request

@barbajs barbajs deleted a comment from stale bot Jun 1, 2022
@xavierfoucrier
Copy link
Member

Yes, it's still planned, no need to bump again.
I am reopening the issue in order for everyone to know.

Thanks again for your patience 😉

@xavierfoucrier xavierfoucrier reopened this Jun 1, 2022
@dacmail
Copy link

dacmail commented Jul 14, 2022

Thanks @stepanjakl I'm also working to get link[rel=stylesheet] elements from head! It would be nice if it were included in @barba/head

@aaronstezycki
Copy link

Any further updates on this?

I think now with http2, there's not as much need to have everything bundled into a single file and progressively load scripts based on the page your on, including using CDNs.

Forgive me if I'm wrong, but hasn't this been planned for 2 years or more?

@xavierfoucrier
Copy link
Member

@aaronstezycki As soon as we will find time to work on this, but since Barba v2 release, it is not a priority: this explained why we haven't worked on this since the beginning. Even with http2, it's still a good practice to bundle everything into a single file, especially when working with dynamic imports. And finally, it really depends on the app you are building.

Anyway, the issue is still opened and we know that in certain cases, the head plugin could be useful.
Thanks for your patience! 😉

👋 Keep in mind that:

  • this project is open source / still maintained
  • not sponsored (as of today we have no sponsors)
  • contributors are working on it on their own free time (for free)

@aaronstezycki
Copy link

Okay, that's a fair answer. :)

I would say though, the everything in this statement could be argued against. Http2 was created to allow for more freedom to separate files and suffers less from multi-file bottlenecks. Like you proceed to say, depends on the app though. Large libraries/scripts would preferably be only downloaded on the page they are being used on, i.e login scripts, large SPA's etc.

Anyway, thanks for reply, .ps I'd be up for donating page.

@xavierfoucrier
Copy link
Member

Thanks @aaronstezycki 😉

I am not an expert in http2, but as I said, it depends on the application, and today with code splitting / three shaking / dynamic imports, it's still possible to have a consistent+robust app with only one bundle. But, it also depends on what you want to do for your clients, because needs / possibilities can differ from a project to another.

Currently, there is no donating / collective page for the BarbaJS project, but you can support maintainers using Github Sponsors, what I highlighted in the beginning of 2022 here on Slack: https://barbajs.slack.com/files/TFDHZ8NN5/F030B08EB8U.

I will probably update the README to make this more clear in the future.

Thanks anyway for your support in open source projects! ✌️

@driespieters
Copy link

I'm trying to integrate Barba in a Shopify theme. Even though I bundle css & js to a single file, Shopify also ads their own script tags to the head depending on the page type. (For example: On product page support for accelerated payment methods like Apple Pay, Marketing pixels for tracking, Cart functionality etc)

The head plugin would be a perfect use case for this. Would be great if this could be considered again. Thank you!

@Messa1

This comment was marked as duplicate.

@dsplz

This comment was marked as duplicate.

@dviate

This comment was marked as duplicate.

1 similar comment
@fifle

This comment was marked as duplicate.

@xavierfoucrier

This comment was marked as duplicate.

@dizplayy

This comment was marked as duplicate.

@xavierfoucrier
Copy link
Member

⚠️ Please everyone, stop adding more +1 to this thread, it's clearly useless since I already know this is an important feature for many of you.

Thanks!

@barbajs barbajs deleted a comment from sbme123 Aug 17, 2023
@barbajs barbajs locked as too heated and limited conversation to collaborators Aug 17, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests