IP Geolocation Finder Tool

IP Geolocation Finder Tool

Lookup IP Address

Lookup History

Your lookup history will appear here.

${escapeHTML(log.ip)}: ${escapeHTML(log.location)} (${escapeHTML(log.isp)})

`).join(''); } function logEntry(data) { const timestamp = new Date().toLocaleString('en-US'); const logItem = { timestamp, ip: data.query, location: `${data.city || 'N/A'}, ${data.country || 'N/A'}`, isp: data.isp || 'N/A', fullData: data // Store full data for PDF log }; lookupLog.unshift(logItem); if (lookupLog.length > 50) lookupLog.pop(); // Limit log size saveState(); renderLog(); } function renderResults(data) { currentResult = data; ui.resIp.textContent = escapeHTML(data.query); ui.resLocation.textContent = `${escapeHTML(data.city)}, ${escapeHTML(data.regionName)}, ${escapeHTML(data.country)}`; ui.resIsp.textContent = escapeHTML(data.isp); ui.resOrg.textContent = escapeHTML(data.org); const mapLink = `https://maps.google.com/?q=${data.lat},${data.lon}`; ui.resMap.innerHTML = `${mapLink}`; ui.loader.style.display = 'none'; ui.resultsContainer.style.display = 'block'; } function showMessage(message, isError = true) { ui.errorMsg.textContent = message; ui.errorMsg.style.display = 'block'; } // --- API LOGIC --- async function fetchIpData(ip = '') { ui.loader.style.display = 'block'; ui.resultsContainer.style.display = 'none'; ui.errorMsg.style.display = 'none'; try { // Using http://ip-api.com, which is free and has CORS enabled. // Note: The free endpoint does not support HTTPS. const response = await fetch(`http://ip-api.com/json/${encodeURIComponent(ip)}`); if (!response.ok) { throw new Error(`API request failed with status ${response.status}`); } const data = await response.json(); if (data.status === 'fail') { throw new Error(data.message); } renderResults(data); logEntry(data); } catch (error) { console.error("IP Geolocation Fetch Error:", error); showMessage(error.message); } finally { ui.loader.style.display = 'none'; } } // --- PDF LOGIC --- function downloadPDF(type) { const { jsPDF } = window.jspdf; if (!jsPDF || !window.jspdf.autoTable) { alert("PDF library not loaded!"); return; } const doc = new jsPDF(); if (type === 'current') { if (!currentResult.query) { alert("Please run a lookup before downloading."); return; } doc.setFontSize(18); doc.text(`IP Geolocation Report: ${currentResult.query}`, 14, 22); doc.autoTable({ startY: 30, theme: 'grid', body: [ ['IP Address', currentResult.query], ['Location', `${currentResult.city}, ${currentResult.regionName}, ${currentResult.country}`], ['Coordinates', `${currentResult.lat}, ${currentResult.lon}`], ['ISP', currentResult.isp], ['Organization', currentResult.org], ] }); doc.save(`IP_Report_${currentResult.query}.pdf`); } else if (type === 'log') { if (lookupLog.length === 0) { alert("Log is empty. Please perform a lookup first."); return; } doc.setFontSize(18); doc.text("IP Geolocation Lookup Log", 14, 22); doc.autoTable({ startY: 30, head: [['Timestamp', 'IP Address', 'Location', 'ISP']], body: lookupLog.map(log => [log.timestamp, log.ip, log.location, log.isp]), theme: 'striped', headStyles: { fillColor: [8, 145, 178] } // var(--primary-color) }); doc.save("IP_Geolocation_Log.pdf"); } } // --- EVENT LISTENERS --- ui.form.addEventListener('submit', e => { e.preventDefault(); const ip = ui.input.value.trim(); fetchIpData(ip); // API handles empty string as "my IP" }); ui.findMeBtn.addEventListener('click', () => { ui.input.value = ''; fetchIpData(''); }); ui.downloadReportBtn.addEventListener('click', () => downloadPDF('current')); ui.downloadLogBtn.addEventListener('click', () => downloadPDF('log')); ui.clearLogBtn.addEventListener('click', () => { lookupLog = []; saveState(); renderLog(); }); // --- TABBING LOGIC --- function switchTab(targetTabId) { ui.tabContents.forEach(c => c.classList.remove('active')); ui.tabButtons.forEach(b => b.classList.remove('active')); document.getElementById(`ipg-tab-${targetTabId}`).classList.add('active'); document.querySelector(`.ipg-tab-button[data-tab="${targetTabId}"]`).classList.add('active'); } function navigateTabs(dir) { const tabs = Array.from(ui.tabButtons); const active = tabs.find(t => t.classList.contains('active')); let index = tabs.indexOf(active) + dir; if (index < 0) index = 0; if (index >= tabs.length) index = tabs.length - 1; switchTab(tabs[index].dataset.tab); } ui.tabButtons.forEach(button => button.addEventListener('click', () => switchTab(button.dataset.tab))); ui.nextTabBtn.addEventListener('click', () => navigateTabs(1)); ui.prevTabBtn.addEventListener('click', () => navigateTabs(-1)); // --- UTILITY --- function escapeHTML(str) { if (typeof str !== 'string') return ''; const p = document.createElement('p'); p.textContent = str; return p.innerHTML; } // --- INITIALIZATION --- loadState(); renderLog(); });
Scroll to Top