Clean UX on page load: Add a loading screen in your app pages in order to not see the blocks being re-arranged

Hi All,

FIRST OF ALL: THE DEMO PAGE

You may have noticed that any Softr page loads their blocks in an ugly way, sometimes (blocks are loaded one by one then re-arranged… not very cool UX).

So, you also may have noticed that when you enter the Softr public community (made in Discourse) there is a loading background displayed, waiting for all the content to be fully loaded before displaying the page content.

Let’s do the same for your app!

I) Code to be inserted in the header of your page or app (for all the pages) settings

<div id="loading-spinner">
  <i class="fas fa-spinner fa-spin"></i>
</div>

<style>
#loading-spinner {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-color: white;
  opacity: 1;
  display: flex;
  justify-content: center;
  align-items: center;
  z-index: 9999;
}

#loading-spinner i {
  font-size: 60px;
  color: #000000;
}
</style>

II) Code to be inserted in the footer of the page or app (for all the pages) settings

<script>
window.addEventListener('load', function() {
  var spinner = document.getElementById('loading-spinner');
  spinner.style.display = 'none';
});
</script>

Precision: in the first code it is possible to set a blur effect. In order to do this, replace 1 by 0.9 or 0.8 in this line of code in the <style> , opacity: 1;

The spinner is customizable (size and color) here: #loading-spinner i { font-size: 60px; color: #000000; }

The white background can be of an other color if you change this line of code: background-color: white;

Thanks

11 Likes

If you want to add a text next to the spinner, like “website-name is loading…” here is the updated code (no need to update the Javascript part in the footer).

On tablet and mobile devices it will be displayed as a column layout (spinner above the text).

<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.3/css/all.min.css">

<div id="loading-spinner">
  <i class="fas fa-spinner fa-spin"></i>
  <p class="loading-text">Website-name is loading...</p>
</div>


<style>
#loading-spinner {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-color: white;
  opacity: 1;
  display: flex;
  justify-content: center;
  align-items: center;
  z-index: 9999;
}

#loading-spinner i {
  font-size: 60px;
  color: #000000;
}

.loading-text {
  font-family: Arial, sans-serif;
  font-size: 24px;
  font-weight: bold;
  color: #000000;
  margin-left: 20px;
  margin-top: 20px;
}

@media (max-width: 768px) {
  #loading-spinner {
    flex-direction: column;
  }
  
  .loading-text {
    margin-left: 0px;
  }
}
</style>
4 Likes

Oh that’s great Matthieu. I was looking for that. Thanks!!!

1 Like

This updated text actually gives me a 504 Gateway 80% of the time.
Super cool besides that, thanks so much!!

Hi Tim,
I can’t reproduce it, works fine on my end.
The page where it doesn’t work is climateu.earth if I’m right?

If 504 error, it is possible that the problem comes from your website, for example a temporary outage from Softr.

Also, I noticed you inserted a JS code in the header in your website, if I’m not wrong, ruling text sizes when the screen is < 768px. A conflict with this one may be the reason.
(and JS codes are always better in the footer)

1 Like

You are my softr HERO Matthieu, this was one of those nagging issues on my radar (that probably I’d never get around to figuring out because all the other more high priority real issues I’ve been trying to resolve)… what a lovely surprise, you already figured it out for me :sob: :pray:

1 Like

Hey Matthieu,
Looks like it had nothing to do with your code, I added it now and it works perfectly.
There shouldn’t be any code in my website header though besides your code?

Final thought/question:
Is there any way to rotate the text that is being portrayed?
I’m portraying “Cooling the planet…” now on every page as it is being loaded (which is AWESOME!!!) - it would be so cool if I could rotate that text and show different strings to keep the loading experience fun → “Capturing Carbon”, “Reaching net-zero”, “Planting trees”…

Any idea how feasible this is?

PS: I’m so thankful for your building this!! Instantly upgraded user experience. Drinks on me!

In your header, there could be other codes, no problem.
Here is a rule that works in 99% of the use cases.

<style> => in the header (and anything related to style needs to stay in one and only one <style> </style> tag => no need to create multiple ones.)

<script> => in the footer. Otherwise the script will be loaded too soon - can create conflict on page loading.

For routing, this should be possible yes, I will try to do it this week.
The other solution, if your website is not too wide, is to insert the two codes page by page and change the text label each time, by hand.

But yes routing would be way easier :sweat_smile:

1 Like

Thanks so much, I’ll make sure to not mess that up :smiley:

And if you have the time, I would obviously love that instead of always adding individual code to every new page and changing it up haha; but it’s definitely a (painful) work around for now :smile:

Update: generate a loading screen with a dynamic text.

Here the dynamic text will be the title of your page. Demo page is updated: https://test-play.softr.app/

As there was a real delay to display the dynamic text, I’m going to show you the exact opposite of what I told @Tim_ClimatEU above = put a JS code in the header :upside_down_face:, but that is for the best!

So here is the code, to be inserted in the header of your app

<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.3/css/all.min.css">

<div id="loading-spinner">
  <i class="fas fa-spinner fa-spin"></i>
  <p class="loading-text"></p>
</div>

<style>
#loading-spinner {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-color: white;
  opacity: 1;
  display: flex;
  justify-content: center;
  align-items: center;
  z-index: 9999;
}

#loading-spinner i {
  font-size: 60px;
  color: #000000;
}

.loading-text {
  font-family: Arial, sans-serif;
  font-size: 24px;
  font-weight: bold;
  color: #000000;
  margin-left: 30px;
  margin-top: 20px;
}

@media (max-width: 768px) {
  #loading-spinner {
    flex-direction: column;
  }
  
  .loading-text {
    margin-left: 0px;
  }
}
</style>

<script>
  window.addEventListener('load', function() {
    var spinner = document.getElementById('loading-spinner');
    spinner.style.display = 'none';
  });

  document.querySelector('.loading-text').textContent = document.title + ' is loading...';
</script>
2 Likes

You are a hero @matthieu_chateau . I was thinking to add such a thing (without knowing how) the last few days. Our airtable base is maxed out and seems to be needing up to 30seconds to even show anything which would probably make any visitor feel as if the website was down apart from me, who knows that something will be there after 30 seconds. Being able to display “WAIT! We’re loading!” is super important for me.
So THANKS A LOT!!!

You’re welcome David! Glad I could help that much!

Update: set different loading icons.

Only in this part of the code :point_down:

<div id="loading-spinner">
  <i class="fas fa-spinner fa-spin"></i>
  <p class="loading-text"></p>
</div>

Replace "fas fa-spinner fa-spin"
By one of them:

"fas fa-spinner fa-spin"
"fas fa-circle-notch fa-spin"
"fas fa-sync fa-spin"
"fas fa-cog fa-spin"
"fas fa-spinner fa-pulse"
"fas fa-stroopwafel fa-spin"
"fas fa-snowboarding fa-spin"

These icons should work without signing up to fontawesome

You can find the reference here to view what do they look like: Animate Icons | Font Awesome Docs

You also can benefit from the last version of fontawesome (6.4.0)
An example you can try (this is to be replaced in the first part of the code, as you can easily see. Careful the <link rel is different)

<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"/>

<div id="loading-spinner">
  <i class="fa-solid fa-heart fa-beat" style="--fa-animation-duration: 0.5s;" ></i>
  <p class="loading-text">Website-name is loading...</p>
</div>

Here is the documentation: Animating Icons | Font Awesome Docs

4 Likes

Amazing, thanks so much!!
Any easy way to insert multiple text snippets yet that change every time it loads? :sunglasses:

I already gave a code to dynamically change the text in the loader screen according to the page title, but maybe you would like something else? Feel free to ask, I will tell you if it’s too much work to do or if it’s feasible in no time.

Yes, I saw that, so cool!! My page title are just not very exciting :smile:
In my case, I would love to have placeholders for different strings that alternate, not the page’s title.
Is that complex?

Here is what I can propose:

You decide of a text according to the url slug. For example when the url slug is “/this” then the displayed text will be “Welcome to this this funny page, we are loading happiness”. You can add as many else if as you wish

<script>
  window.addEventListener('load', function() {
    var spinner = document.getElementById('loading-spinner');
    spinner.style.display = 'none';
  });

  var loadingText = '';
  var url = window.location.href.toLowerCase();

  if (url.includes('/this')) {
    loadingText = 'Welcome to this this funny page, we are loading happiness';
  } else if (url.includes('/resources')) {
    loadingText = 'Loading our resources, knowledge needs patience.';
  } else {
    loadingText = 'Loading, please wait...';
  }

  document.querySelector('.loading-text').textContent = loadingText;
</script>

It works on my end! - I put it in the header below the rest of the code (below styles). Does this suit you?

1 Like

That’s a nice enhancement @matthieu_chateau .

I think @Tim_ClimatEU possibly looks for full randomness, regardless of the page title.

Something like this might work:

<script>
  window.addEventListener('load', function() {
    var spinner = document.getElementById('loading-spinner');
    spinner.style.display = 'none';
  });

  var loadingTexts = [
    'Loading, please wait...',
    'Welcome to this funny page, we are loading happiness',
    'Loading our resources, knowledge needs patience.',
    'Hold tight, we are preparing something special for you',
    'Get ready for awesomeness, we are loading...',
    'Patience is a virtue, we are loading the page...',
  ];

  var randomIndex = Math.floor(Math.random() * loadingTexts.length);
  var loadingText = loadingTexts[randomIndex];

  document.querySelector('.loading-text').textContent = loadingText;
</script>
1 Like

This works well too!

@matthieu_chateau yes, what @J_1 is proposing is what I’m looking for. Working with the slug wouldn’t work for me either unfortunately :slight_smile:

However, the script of @J_1 doesn’t seem to work for me when I add it to the header? Thanks so much for putting this together!!