Skip to main content

Loading content after page load Ready

This template shows how to build a simple loading state when some of the page content is loaded after the initial page load. Please note that the example below does not represent a real use case. Adjust the style of the messages and other details as required by the design.

Hint: Press F on your keyboard to view both templates and components in fullscreen and ESC to exit the fullscreen mode. You can also open the template in a new browser window.


Open in new window
<!DOCTYPE html>
<html lang="fi">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1.0" />
<title>LähiTapiola</title>
<link rel="stylesheet" href="https://cdn.duetds.com/api/fonts/3.0.71/lib/localtapiola.css" integrity="sha384-5JYmtSD7nykpUvSmTW1CHMoBDkBZUpUmG0vuh+NUVtZag3F75Kr7+/JU3J7JV6Wq" crossorigin="anonymous" />
<link rel="stylesheet" href="https://cdn.duetds.com/api/css/5.2.0/lib/duet.min.css" integrity="sha384-ROReInsG2SZ7Ez7yRxNLeGCtwHEQx1VrMnV01yi3A9fhpNHIfzc9q1crXm1z9UiL" crossorigin="anonymous" />
<link rel="stylesheet" href="https://cdn.duetds.com/api/tokens/5.1.6/lib/tokens.custom-properties.css" integrity="sha384-CLtvX3Hm5cg7+ALJG+wzT72Bmxt2YN1piNjcK8ILizklnRCExM6i3lvmYJKW4At4" crossorigin="anonymous" />
<script type="module" src="https://cdn.duetds.com/api/components/10.8.1/lib/duet/duet.esm.js" integrity="sha384-lMkgfB8TD9On19ZAZhIv4jP2o82G7hy/HzonI3UbMqCEeiwNobVJjOgY1i2OgJR+" crossorigin="anonymous"></script>
</head>
<body>
<duet-layout center middle>
<div slot="main">
<duet-heading level="h1">Page with content that is loaded after page load</duet-heading>
<duet-paragrap>
Some of the content is added to this page only after the initial page load.
We need to announce to screen reader users once it is available.</duet-paragrap>
<duet-divider></duet-divider>
<duet-spacer></duet-spacer>

<duet-spacer size="xx-large"></duet-spacer>

<div id="dynamic-content"></div>
<div id="live-content" aria-live="polite"></div>
</div>
</duet-layout>


<template id="loader-panel-template">
<duet-panel variation="secondary" class="duet-text-center">
<duet-paragraph weigh="semibold">
<span>Loading content, please wait.</span>
</duet-paragraph>
<div>
<duet-spinner size="large" color="primary"></duet-spinner>
</div>
</duet-panel>
</template>


<template id="dynamic-data-template">
<div class="dynamic-data">
<duet-heading level="h2">Some dynamic data</duet-heading>
<duet-table>
<table>
<thead>
<tr>
<th>Foo</th>
<th>Bar</th>
<th>Baz</th>
</tr>
</thead>
<tbody>

</tbody>
</table>
</duet-table>
</div>
</template>

<template id="loading-complete-template">
<duet-visually-hidden aria-live="polite">
The data loading is complete.
</duet-visually-hidden>
</template>

<style>
div:has(duet-spinner) {
position: relative;
height: 8rem;
}
</style>

<script>
const contentHolder = document.getElementById("dynamic-content")
const liveContentHolder = document.getElementById("live-content")
const loaderTemplate = document.getElementById("loader-panel-template")
const dataTemplate = document.getElementById("dynamic-data-template")
const completionTemplate = document.getElementById("loading-complete-template")

const startLoading = () => {

const dataWeAreLoding = document.importNode(dataTemplate.content, true)
const loaderPanel = document.importNode(loaderTemplate.content, true)
const completionMessage = document.importNode(completionTemplate.content, true)
// we use span inside the duet-paragraph for changing text to ensure screen readers access it correctly
const textContainer = loaderPanel.querySelector("duet-paragraph span")

liveContentHolder.appendChild(loaderPanel)

setTimeout(() => {
textContainer.textContent = "Taking a bit longer than expected, please be patient."
}, 5000)

setTimeout(() => {
const body = dataWeAreLoding.querySelector("tbody")
for (let r = 0; r < 100; r++) {
const tr = document.createElement("tr")
for (let c = 0; c < 3; c++) {
const td = document.createElement("td")
td.textContent = Math.round(Math.random() * 1000)
tr.append(td)
}
body.append(tr)
}

liveContentHolder.querySelector("duet-panel").remove()
contentHolder.appendChild(dataWeAreLoding)
liveContentHolder.appendChild(completionMessage)
}, 10000)
}

startLoading()
</script>
</body>
</html>

Integration

To install this template’s dependencies into your project, run:

npm install @duetds/components
npm install @duetds/css
npm install @duetds/fonts

For further guidelines, please see each package’s documentation.



Tutorials

Follow these practical tutorials to learn how to build simple page layouts using Duet’s CSS Framework, Web Components and other features:

Tutorials

Building Layouts

Tutorials

Using CLI Tools

Tutorials

Creating Custom Patterns

Tutorials

Server Side Rendering

Tutorials

Sharing Prototypes

Tutorials

Usage With Markdown


Troubleshooting

If you experience any issues while using a template, please head over to the Support page for more guidelines and help.