<main id="info">
  <p><strong></strong>
    <span id="flag" class=""></span>
    <span id="country"></span>
  </p>
  <p><strong>Your City</strong> <span id="city"></span></p>
  <p><strong>Your IP</strong> <span id="ip-address"></span></p>
</main>
body {
  font-family: sans-serif;
  margin: 0;
}

#info {
  text-align: center;
  margin-top: 75px;
}
// re: Sitepoint question on reformatting a jquery ajax request to vanilla JS
// https://www.sitepoint.com/community/t/json-api-and-apps/378157

// helper function for convenience
const getElem = (selector, root = document) => root.querySelector(selector)

const addClasses = (elem, classNames) => {
  elem.classList.add(...classNames.trim().split(' '))
}

// Note: by default request is blocked by UBlock Origin
fetch('https://freegeoip.app/json/', {credentials: 'include', mode: 'cors'})
  .then(response => response.json())
  .then(
    // used destructuring to get data properties
    ({country_name, country_code, city, ip}) => {
        const countryClassName = `flag-icon-${country_code.toLowerCase()}`

        getElem('#country').textContent = country_name
        getElem('#city').textContent = city
        getElem('#ip-address').textContent = ip
        // with classList.add multiple classnames need to be comma separated
        getElem('#flag').classList.add('flag-icon', countryClassName)
      }
    )
    .catch((error) => {
      console.error('Error:', error);
    })
Run Pen

External CSS

  1. https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/2.8.0/css/flag-icon.min.css

External JavaScript

This Pen doesn't use any external JavaScript resources.