Creating JavaScript Routes for WordPress Website with Stream CSS Progress Bar
Tags: javascript, wordpress, webdev, frontend
Published: 2023-06-22 16:53:39


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jn4p30mss4ydgr1kr34k.png)

In this article, we will learn how to create JavaScript routes for a WordPress website, allowing smooth client-side navigation, and implement a stream CSS progress bar to enhance the user experience. We'll be using native JavaScript without any frameworks or libraries. By the end of this tutorial, you will have a solid understanding of how to build JavaScript routes and implement a stream CSS progress bar in your WordPress website.

## Prerequisites
To follow along with this article, you should have a basic understanding of HTML, CSS, and JavaScript. Additionally, familiarity with WordPress and its templating system will be beneficial.

## Getting Started
Before we dive into the code, make sure you have a WordPress website up and running. Create a new directory in your theme directory and name it **js**. Inside the **js** directory, create a new file called **main.js**. This will be our main JavaScript file where we'll implement the JavaScript routes and stream CSS progress bar.

Open the **functions.php** file of your WordPress theme and enqueue the **main.js** file. Add the following code to your **functions.php** file:

```php
function enqueue_custom_scripts() {
    wp_enqueue_script( 'custom-scripts', get_template_directory_uri() . '/js/main.js', array(), '1.0', true );
}
add_action( 'wp_enqueue_scripts', 'enqueue_custom_scripts' );
```

This code ensures that the **main.js** file is loaded on the frontend of your WordPress website.

## Set Up the Stream Progress Bar
1. Open your WordPress theme's header.php file.
2. Add a stream progress bar element to the HTML structure. For example:

```html
<div class="progress-bar-container">
  <div class="progress-bar"></div>
</div>
```
## Implementing JavaScript Routes
Now, let's start implementing JavaScript routes for our WordPress website. Open the **main.js** file and add the following code:

```javascript
document.addEventListener("DOMContentLoaded", function () {
  const progressBar = document.getElementById("progress-bar");
  // Update the progress bar width based on the loading percentage
  function updateProgressBar(percentage) {
    progressBar.style.width = `${percentage}%`;
    progressBar.classList.add("filled");
    // hide progress bar when content is loaded
    if (percentage == 100) {
      setTimeout(() => {
        progressBar.classList.remove("filled");
        progressBar.style.width = 0;
      }, 300);
    }
  }
  // Fetch content based on the URL and update the page
  function fetchContent(url) {
    updateProgressBar(0); // Reset progress bar
    console.log(url);
    fetch(url, {
      headers: {
        "Content-Type": "text/html; charset=utf-8",
      },
      mode: "cors",
    })
      .then((response) => {
        const reader = response.body.getReader();
        const decoder = new TextDecoder("utf-8");
        const total = +response.headers.get("Content-Length");
        let loaded = 0;
        let html = "";
        function read() {
          reader.read().then(({ done, value }) => {
            if (done) {
              const parser = new DOMParser();
              const doc = parser.parseFromString(html, "text/html");
              // Extract the specific HTML element and their child's from the parsed document
              const primary = doc.querySelector("#primary");
              // take content element from current page
              const appContainer = document.getElementById("content");
              if (primary) {
                // Then, Remove all child elements
                while (appContainer.firstChild) {
                  appContainer.removeChild(appContainer.firstChild);
                }
                // Append a new element
                appContainer.appendChild(primary);
              } else {
                //  open it regular
                return window.open(url, "_self");
              }
              updateProgressBar(100); // Set progress bar to 100% when content is loaded
              return;
            }
            loaded += value.length;
            updateProgressBar((loaded / total) * 100);
            const chunk = decoder.decode(value, { stream: true });
            html += chunk;
            // Process the content here if needed
            // somthing like pelase wait or spinner..
            read(); // Continue reading the stream
          });
        }
        read();
      })
      .catch((error) => {
        console.error(error);
        updateProgressBar(0); // Reset progress bar in case of errors
      });
  }
  // Handle link clicks
  function handleLinkClick(event) {
    const target = event.target;
    // Check if the clicked element or its parent is an anchor element
    const anchor = target.closest("a");
    if (anchor) {
      event.preventDefault();
      // Get the href attribute of the anchor element
      const targetUrl = anchor.getAttribute("href");
      try {
        // Update the URL and push a new history state
        history.pushState(null, "", targetUrl);
      } catch (error) {
        return window.open(targetUrl, "_self");
      }
      // Fetch and load the content for the clicked link
      fetchContent(targetUrl);
    }
  }
  // Attach click event listeners to all links
  const allLinks = document.querySelectorAll("a");
  allLinks.forEach((link) => {
    link.addEventListener("click", handleLinkClick);
  });
  // Handle the popstate event to update the page when the user navigates back/forward
  window.addEventListener("popstate", () => {
    fetchContent(window.location.href);
  });
});

```
In the above code, we first attach an event listener to the **DOMContentLoaded** event to ensure our JavaScript code runs when the page has finished loading.

The **handleLinkClick** function is responsible for intercepting link clicks, preventing the default behavior, starting the progress bar animation, and fetching the content for the clicked link using the **fetchContent** function.

The **fetchContent** function sends a GET request to the target URL, retrieves the response as text, stops the progress bar animation, and updates the content container with the fetched HTML.

Make sure to have a CSS file linked to your HTML, where you can define the styles for the progress bar animation. Here's a basic CSS example for the progress bar:

```css
.progress-bar-container {
  width: 100%;
  height: 2px;
  background-color: transparent;
  position: absolute;
  top: 0;
  display: block;
}

.progress-bar {
  width: 0;
  height: 100%;
  background-color: #f00;
  position: relative;
  transition: width 0.3s ease-in-out;
  opacity: 0;
}
.progress-bar.filled {
  opacity: 1;
}
/* Optional: Add animation to the progress bar */
@keyframes progress-animation {
  0% {
    width: 0;
  }
  100% {
    width: 100%;
  }
}
```

With this setup, whenever a link is clicked on your WordPress website, the JavaScript code will intercept the click event, initiate the progress bar animation, fetch the content for the clicked link, and update the content container seamlessly.

Feel free to customize the CSS styles to match your website's design.

That's it! You have successfully implemented JavaScript routes with a stream CSS progress bar for your WordPress website. Users will now experience smooth and visually appealing navigation between different pages.