Building a DNS Propagation Checker with Vite + Svelte

Introduction

In the digital age of DNS Propagation, ensuring that DNS changes propagate correctly across the internet is crucial for maintaining the accessibility and reliability of websites. To address this need, I built a DNS Propagation Checker using Svelte. This tool allows users to check the propagation of DNS records across multiple DNS servers and visualize server locations on an interactive globe. In this blog post, I’ll walk you through the features, technology stack, and benefits of this project.

Why DNS Propagation Matters

When you update DNS records, such as changing the IP address of your domain, it takes time for these changes to propagate across all DNS servers worldwide. During this propagation period, some users might still see the old DNS records, leading to potential downtime or accessibility issues. A DNS Propagation Checker helps you monitor this process, ensuring that your changes have been applied universally.

Features of the DNS Propagation Checker

1. Check DNS Propagation:

▪ Enter a domain name and select the DNS record type (A, AAAA, CNAME, MX, NS, SOA, TXT).

▪ (Optional) Enter an expected IP address to highlight matching records.

▪ Click the “Check” button to start the DNS propagation check.

2. Interactive Globe:

▪ Visualize server locations on an interactive globe using Cobe.

▪ See the geographical distribution of DNS servers and their response statuses.

3. Record Type Support:

▪ Supports various DNS record types, including A, AAAA, CNAME, MX, NS, SOA, and TXT.

4. Expected IP Highlighting:

▪ Highlights matching DNS records in green.

▪ Highlights non-matching DNS records in red.

Technology Stack

The DNS Propagation Checker is built using the following technologies:

Svelte: A modern JavaScript framework for building fast and reactive user interfaces.

Cobe: A lightweight WebGL globe library for visualizing server locations.

NetworkCalc DNS API: An API for fetching DNS records for a given hostname.

Vercel: A platform for deploying serverless functions and static sites.

Building the Application

Setting Up the Project

To start, I set up a new Vite + Svelte project and installed the necessary dependencies:

npm create vite@latest dns-propagation-checker -- --template vue
cd dns-propagation-checker
npm install

Creating the DNS Propagation Checker Form

I created a form that allows users to input a domain name, select a DNS record type, and optionally enter an expected IP address. The form also includes a button to trigger the DNS propagation check.

<form on:submit|preventDefault={checkPropagation}>
        <input
          type="text"
          bind:value={domain}
          placeholder="Enter domain name"
          required
        />
        <select bind:value={recordType}>
          <option value="A">A</option>
          <option value="AAAA">AAAA</option>
          <option value="CNAME">CNAME</option>
          <option value="MX">MX</option>
          <option value="NS">NS</option>
          <option value="TXT">TXT</option>
        </select>
        <button
          class="expectedBtn"
          type="button"
          on:click={() => (showExpected = !showExpected)}
          ><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"
            ><path
              class="fa-secondary"
              opacity=".4"
              d="M192 256a64 64 0 1 0 128 0 64 64 0 1 0 -128 0z"
            /><path
              class="fa-primary"
              d="M489.6 191.2c6.9-6.2 9.6-15.9 6.4-24.6c-4.4-11.9-9.7-23.3-15.8-34.3l-4.7-8.1c-6.6-11-14-21.4-22.1-31.2c-5.9-7.2-15.7-9.6-24.5-6.8l-55.7 17.7C359.8 93.6 345 85 329.2 78.4L316.7 21.3c-2-9.1-9-16.3-18.2-17.8C284.7 1.2 270.5 0 256 0s-28.7 1.2-42.5 3.5c-9.2 1.5-16.2 8.7-18.2 17.8L182.8 78.4c-15.8 6.5-30.6 15.1-44 25.4L83.1 86.1c-8.8-2.8-18.6-.3-24.5 6.8c-8.1 9.8-15.5 20.2-22.1 31.2l-4.7 8.1c-6.1 11-11.4 22.4-15.8 34.3c-3.2 8.7-.5 18.4 6.4 24.6l43.3 39.4C64.6 238.9 64 247.4 64 256s.6 17.1 1.7 25.4L22.4 320.8c-6.9 6.2-9.6 15.9-6.4 24.6c4.4 11.9 9.7 23.3 15.8 34.3l4.7 8.1c6.6 11 14 21.4 22.1 31.2c5.9 7.2 15.7 9.6 24.5 6.8l55.7-17.7c13.4 10.3 28.2 18.9 44 25.4l12.5 57.1c2 9.1 9 16.3 18.2 17.8c13.8 2.3 28 3.5 42.5 3.5s28.7-1.2 42.5-3.5c9.2-1.5 16.2-8.7 18.2-17.8l12.5-57.1c15.8-6.5 30.6-15.1 44-25.4l55.7 17.7c8.8 2.8 18.6 .3 24.5-6.8c8.1-9.8 15.5-20.2 22.1-31.2l4.7-8.1c6.1-11 11.4-22.4 15.8-34.3c3.2-8.7 .5-18.4-6.4-24.6l-43.3-39.4c1.1-8.3 1.7-16.8 1.7-25.4s-.6-17.1-1.7-25.4l43.3-39.4zM256 160a96 96 0 1 1 0 192 96 96 0 1 1 0-192z"
            /></svg
          ></button
        >
        {#if showExpected}
          <input
            type="text"
            bind:value={expectedIp}
            placeholder="Expected Result (optional)"
          />
        {/if}

        <button type="submit" disabled={loading}>Check</button>
      </form>

Fetching DNS Records

I used the NetworkCalc DNS API to fetch DNS records for the given domain and record type. The results are then displayed in a list, with matching records highlighted in green and non-matching records highlighted in red.

async function performCheckPropagation() {
    try {
      const fetchPromises = dnsServers.map(async (server) => {
        const [dnsResult, location] = await Promise.all([
          fetch(`https://networkcalc.com/api/dns/lookup/${domain}`)
            .then((response) => response.json())
            .catch((err) => ({ error: err.message })),
          getServerLocation(server.ip),
        ]);
        markers.push({ location: [location.lat, location.lng], size: 0.03 });
        return {
          server: server.name,
          ip: server.ip,
          dnsResult: dnsResult.records[recordType],
          location,
        };
      });
      results = await Promise.all(fetchPromises);
      markersReady = true;
      //console.log("Markers:", markers);
    } catch (err) {
      error = err.message;
    } finally {
      loading = false;
    }
  }

  function getHighlightClass(record, type) {
    if (!expectedIp) return "";
    let valueToCompare;
    switch (type) {
      case "A":
      case "AAAA":
        valueToCompare = record.address;
        break;
      case "CNAME":
        valueToCompare = record.address;
        break;
      case "MX":
        valueToCompare = record.exchange;
        break;
      case "NS":
        valueToCompare = record.nameserver;
        break;
      case "TXT":
        valueToCompare = record;
        break;
      default:
        valueToCompare = "";
    }
    return valueToCompare === expectedIp ? "highlight-green" : "highlight-red";
  }

Visualizing Server Locations

To visualize server locations, I integrated the Cobe library, which provides a lightweight WebGL globe. The globe displays markers for each server location, allowing users to see the geographical distribution of DNS servers.

<script>
  import { onMount, onDestroy, afterUpdate } from "svelte";
  import { tick } from "svelte";

  export let markers = [];

  let canvas;
  let globe;

  const initializeGlobe = async () => {
    const createGlobe = (await import("https://cdn.skypack.dev/cobe")).default;

    let phi = 0;

    globe = createGlobe(canvas, {
      devicePixelRatio: 2,
      width: 400 * 2,
      height: 400 * 2,
      phi: 0,
      theta: 0,
      dark: 1,
      diffuse: 2,
      scale: 3,
      mapSamples: 16000,
      mapBrightness: 3,
      baseColor: [0.9, 0.9, 0.9],
      markerColor: [1, 1, 0],
      glowColor: [0.1, 0.1, 0.1],
      offset: [0, 0],
      markers,
      onRender: (state) => {
        state.phi = phi;
        phi += 0.001;
      },
    });
  };

  onMount(() => {
    initializeGlobe();
  });

  afterUpdate(async () => {
    if (markers.length > 0) {
      if (globe) {
        globe.destroy();
      }
      await tick(); // Wait for DOM updates
      initializeGlobe();
    }
  });

  onDestroy(() => {
    if (globe) {
      globe.destroy();
    }
  });
</script>

<canvas bind:this={canvas} style="width: 100%; height: 100%;"></canvas>

<style>
  canvas {
    display: block;
    margin: 0 auto;
    height: 100%;
    width: 100%;
  }
</style>

Conclusion

The DNS Propagation Checker is a powerful tool for monitoring DNS changes and ensuring that they propagate correctly across the internet. By leveraging modern web technologies like Svelte, Cobe, and NetworkCalc DNS API, I was able to build a fast, interactive, and user-friendly application. Whether you’re a web developer, network administrator, or just someone interested in DNS, this tool can help you ensure that your DNS changes are applied universally and correctly.

Check out the live site: projects.lbor.dev/dns-checker/

For the full code feel free to explore the GitHub repository for more details and to contribute to the project.

20% Off Hosting –
Code: 1LUKE485

* first-time purchases of hosting or VPS plans for 12 months or longer using code: 1LUKE485

GET 20% OFF – CODE: 1LUKE485

---- 
Ready for a supercharged online presence with Hostinger? Use my 20% discount link (CODE: 1LUKE485)  to start your journey today. Your website deserves the powerhouse performance that Hostinger delivers.