PageSourceSearch

https://www.talenta.co/wp-content/themes/talenta/parts/geolocation-banner/geolocation-banner.js?ver=1790224959

js talenta.co collected 2026-09-24 09:37:20 UTC 6,312 bytes, 134 lines download raw bytes

1// Set to true to enable ?geo_debug=ID|SG query param for testing
2const GEO_BANNER_DEBUG = true;
3
4// Controls which banner directions are active.
5// showOnEnSgPage : show banner to ID visitors on EN-SG pages  → redirect to ID version
6// showOnIdPage   : show banner to SG visitors on ID pages     → redirect to EN-SG version
7//                  keep false while EN-SG is still no-index / no public entry point
8const GEO_BANNER_ENABLED = {
9    showOnEnSgPage: true,
10    showOnIdPage: true,
11};
12
13const GEO_BANNER_COPY = {
14    idVisitorOnSgPage: {
15        message: "Halo, apakah Anda ingin beralih ke situs berbahasa Indonesia kami?",
16        cta: "Beralih ke Bahasa Indonesia",
17    },
18    sgVisitorOnIdPage: {
19        message: "Hello, do you want to switch to our Singaporean site?",
20        cta: "Switch to Singapore",
21    },
22};
23
24document.addEventListener("DOMContentLoaded", function () {
25    if (localStorage.getItem("hideGeoBanner") === "true") return;
26
27    // Read WPML hreflang tags and detect ID/EN-SG URLs by href pattern
28    const translations = getWPMLTranslations();
29
30    // Only show banner if the current page exists in both ID and EN-SG
31    if (!translations.idUrl || !translations.enSgUrl) return;
32
33    const isEnSgPage = window.location.pathname.includes("/en-sg/");
34
35    getCountryCode()
36        .then((country) => {
37            if (!country) return;
38
39            // ID visitor on EN-SG page
40            if (GEO_BANNER_ENABLED.showOnEnSgPage && country === "ID" && isEnSgPage) {
41                renderBanner(
42                    GEO_BANNER_COPY.idVisitorOnSgPage.message,
43                    translations.idUrl,
44                    GEO_BANNER_COPY.idVisitorOnSgPage.cta,
45                    { ctaId: "geo-banner-cta-to-id", closeId: "geo-banner-close-en-sg" },
46                );
47            }
48            // SG visitor on ID page
49            else if (GEO_BANNER_ENABLED.showOnIdPage && country === "SG" && !isEnSgPage) {
50                renderBanner(
51                    GEO_BANNER_COPY.sgVisitorOnIdPage.message,
52                    translations.enSgUrl,
53                    GEO_BANNER_COPY.sgVisitorOnIdPage.cta,
54                    { ctaId: "geo-banner-cta-to-en-sg", closeId: "geo-banner-close-id" },
55                );
56            }
57        })
58        .catch(() => {
59            console.log("[geo-banner] Could not determine country code, all geo APIs unavailable.");
60        });
61
62    function getWPMLTranslations() {
63        const get = (lang) => {
64            const el = document.querySelector(`link[rel="alternate"][hreflang="${lang}"]`);
65            return el ? el.getAttribute("href") : null;
66        };
67        return {
68            idUrl: get("id"),
69            enSgUrl: get("en-sg"),
70        };
71    }
72
73    function getCountryCode() {
74        if (GEO_BANNER_DEBUG) {
75            const param = new URLSearchParams(window.location.search).get("geo_debug");
76            if (param) return Promise.resolve(param.toUpperCase());
77        }
78
79        const cached = sessionStorage.getItem("geoCountryCode");
80        if (cached) return Promise.resolve(cached);
81
82        return fetchCountryFrom("https://api.country.is/").then((code) => {
83            sessionStorage.setItem("geoCountryCode", code);
84            return code;
85        });
86    }
87
88    function fetchCountryFrom(url) {
89        return fetch(url, {
90            headers: {
91                Accept: "application/json",
92            },
93        })
94            .then((response) => {
95                if (!response.ok) {
96                    throw new Error("Geo request failed");
97                }
98                return response.json();
99            })
100            .then((data) => {
101                const countryCode = (data.country_code || data.countryCode || data.country || "").toUpperCase();
102                if (!countryCode) {
103                    throw new Error("Country code missing");
104                }
105                return countryCode;
106            });
107    }
108
109    function renderBanner(msg, url, ctaLabel, ids) {
110        const banner = document.createElement("div");
111        banner.id = "geo-alert-banner";
112        banner.innerHTML = `
113            <div class="geo-banner" style="position:fixed; bottom:0; left:0; width:100%; display: flex; justify-content: center; align-items: center; gap: 8px; background:#A51C1C; color:#fff; padding:16px; text-align:center; z-index:10000; font-family: 'Inter', sans-serif; font-size:16px; line-height:24px; font-weight:600; ">
114                <div class="icon"><span class="ic"></span><span class="pulse-1"></span><span class="pulse-2"></span></div>
115                <div class="content">
116                ${msg}
117                <a id="${ids.ctaId}" href="${url}" style="color:#fff; display: inline-flex; font-weight:400; text-decoration:underline;">${ctaLabel}</a>
118                </div>
119                <button id="${ids.closeId}" onclick="closeGeoBanner()" style="background:none; border:none; cursor:pointer; display:flex; width:28px;height:28px; align-items:center; justify-content:center; position:absolute; right:20px; top:calc(50%-14px);"><svg width="17" height="17" viewBox="0 0 17 17" fill="none" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M0 8.33333C0 3.73096 3.73096 0 8.33333 0C12.9357 0 16.6667 3.73096 16.6667 8.33333C16.6667 12.9357 12.9357 16.6667 8.33333 16.6667C3.73096 16.6667 0 12.9357 0 8.33333ZM5.57963 4.73783C5.34717 4.50538 4.97029 4.50538 4.73783 4.73783C4.50538 4.97029 4.50538 5.34717 4.73783 5.57963L7.49154 8.33333L4.73783 11.087C4.50538 11.3195 4.50538 11.6964 4.73783 11.9288C4.97029 12.1613 5.34717 12.1613 5.57963 11.9288L8.33333 9.17513L11.087 11.9288C11.3195 12.1613 11.6964 12.1613 11.9288 11.9288C12.1613 11.6964 12.1613 11.3195 11.9288 11.087L9.17513 8.33333L11.9288 5.57963C12.1613 5.34717 12.1613 4.97029 11.9288 4.73783C11.6964 4.50538 11.3195 4.50538 11.087 4.73783L8.33333 7.49154L5.57963 4.73783Z" fill="#F1F5F9"/></svg></button>
120            </div>
121        `;
122        document.body.prepend(banner);
123        document.body.classList.add("has-geobanner");
124    }
125});
126
127function closeGeoBanner() {
128    const banner = document.getElementById("geo-alert-banner");
129    if (banner) {
130        banner.remove();
131    }
132    document.body.classList.remove("has-geobanner");
133    localStorage.setItem("hideGeoBanner", "true");
134}

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.