Skip to content

Commit 7f0a9db

Browse files
committed
Astro Phase 1b: shared BaseLayout + homepage on Astro
Astro Phase 1b: shared BaseLayout + homepage on Astro
1 parent 81bc43f commit 7f0a9db

4 files changed

Lines changed: 351 additions & 6 deletions

File tree

.github/workflows/astro-build-check.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,9 @@ jobs:
3535

3636
- name: Build Astro site
3737
run: npm run build
38+
env:
39+
# QA is served under the GitHub project sub-path. Production omits this (root).
40+
SITE_BASE: /prodipdata.github.io
3841

3942
- name: Overlay legacy pages not yet migrated to Astro
4043
# --ignore-existing means Astro-built pages are NEVER overwritten by legacy

astro.config.mjs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
import { defineConfig } from 'astro/config';
22

3-
// The canonical production site. Used for canonical URLs and the generated sitemap.
4-
// QA/staging serves the same build at a different host; canonical still points here,
5-
// and the hostname-keyed noindex (in site.js) keeps non-production hosts out of search.
3+
// site = canonical production origin (used for canonical URLs + sitemap), always prod.
4+
// base = path the site is served under. Production root = '/'. QA serves under the
5+
// GitHub project sub-path, so the QA workflow sets SITE_BASE=/prodipdata.github.io.
6+
// format='file' keeps existing ".html" URLs (e.g. /platform.html) so links don't break.
67
export default defineConfig({
78
site: 'https://geoiplocations.com',
8-
// output: 'static' is the default — every page is pre-rendered to HTML at build time.
9+
base: process.env.SITE_BASE || '/',
10+
trailingSlash: 'ignore',
911
build: {
10-
// Emit /page/index.html style URLs so existing paths keep working.
11-
format: 'directory'
12+
format: 'file'
1213
}
1314
});

src/layouts/BaseLayout.astro

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
---
2+
// Shared site shell — the one place nav, footer, head meta, OG/Twitter tags,
3+
// canonical, Organization schema, analytics + noindex (via site.js) live.
4+
// Replaces the hand-copied header/footer across 40+ files.
5+
const {
6+
title,
7+
description,
8+
canonicalPath, // e.g. "/" or "/platform.html"
9+
page = '', // data-page
10+
navPage = '', // data-nav-page
11+
assetRoot = '', // data-asset-root (legacy site.js fetch root)
12+
ogTitle,
13+
image = 'https://geoiplocations.com/assets/img/prodipdata-logo.png',
14+
} = Astro.props;
15+
16+
const base = import.meta.env.BASE_URL; // '/prodipdata.github.io/' on QA, '/' on prod
17+
const canonical = 'https://geoiplocations.com' + canonicalPath;
18+
const socialTitle = ogTitle ?? title.replace(/\s*\|\s*(ProdIPData|GeoIP Locations).*$/, '');
19+
20+
const org = {
21+
'@context': 'https://schema.org',
22+
'@type': 'Organization',
23+
'@id': 'https://geoiplocations.com/#organization',
24+
name: 'ProdIPData',
25+
alternateName: 'GeoIP Locations',
26+
url: 'https://geoiplocations.com/',
27+
logo: 'https://geoiplocations.com/assets/img/prodipdata-mark.png',
28+
};
29+
30+
const navItems = [
31+
['platform', 'Platform'],
32+
['coverage', 'Coverage'],
33+
['methodology', 'Methodology'],
34+
['downloads', 'Downloads'],
35+
['docs', 'Documentation'],
36+
['news', 'News'],
37+
['contact', 'Contact'],
38+
];
39+
const link = (slug) => `${base}${slug}.html`;
40+
---
41+
<!doctype html>
42+
<html lang="en">
43+
<head>
44+
<meta charset="UTF-8" />
45+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
46+
<title>{title}</title>
47+
<meta name="description" content={description} />
48+
<link rel="canonical" href={canonical} />
49+
50+
<meta property="og:type" content="website" />
51+
<meta property="og:site_name" content="GeoIP Locations" />
52+
<meta property="og:title" content={socialTitle} />
53+
<meta property="og:description" content={description} />
54+
<meta property="og:url" content={canonical} />
55+
<meta property="og:image" content={image} />
56+
<meta name="twitter:card" content="summary_large_image" />
57+
<meta name="twitter:title" content={socialTitle} />
58+
<meta name="twitter:description" content={description} />
59+
<meta name="twitter:image" content={image} />
60+
61+
<link rel="icon" type="image/png" href={`${base}assets/img/prodipdata-mark.png`} />
62+
<link rel="stylesheet" href={`${base}assets/css/styles.css`} />
63+
<script type="application/ld+json" is:inline set:html={JSON.stringify(org)} />
64+
<slot name="head" />
65+
</head>
66+
<body data-page={page} data-nav-page={navPage} data-asset-root={assetRoot}>
67+
<header class="site-header">
68+
<div class="container">
69+
<div class="navbar glass">
70+
<a class="brand" href={`${base}index.html`}>
71+
<div class="brand-mark">&#9678;</div>
72+
<div>
73+
GeoIP Locations
74+
<small>Powered by ProdIPData</small>
75+
</div>
76+
</a>
77+
<nav class="nav-links" aria-label="Primary navigation">
78+
{navItems.map(([slug, label]) => <a href={link(slug)} data-nav={slug}>{label}</a>)}
79+
</nav>
80+
<div class="header-cta">
81+
<a class="btn btn-secondary" href={`${base}downloads.html`}>Monthly Release</a>
82+
</div>
83+
<button class="menu-button" type="button" data-menu-toggle aria-expanded="false" aria-label="Open menu">Menu</button>
84+
</div>
85+
<nav class="mobile-nav glass" data-mobile-nav>
86+
{navItems.map(([slug, label]) => <a href={link(slug)} data-nav={slug}>{label}</a>)}
87+
</nav>
88+
</div>
89+
</header>
90+
91+
<slot />
92+
93+
<footer class="site-footer">
94+
<div class="container site-footer-inner">
95+
<div>&copy; <span data-current-year></span> GeoIP Locations &middot; ProdIPData</div>
96+
<div><a href={`${base}licensing.html`}>Datasets and metadata: CC BY 4.0</a></div>
97+
<div>Engineered and published by the ProdIPData team.</div>
98+
</div>
99+
</footer>
100+
101+
<script is:inline src={`${base}assets/js/site.js`} defer></script>
102+
</body>
103+
</html>

src/pages/index.astro

Lines changed: 238 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,238 @@
1+
---
2+
import BaseLayout from '../layouts/BaseLayout.astro';
3+
4+
// Page-specific WebSite schema (Organization schema is in BaseLayout).
5+
const website = {
6+
'@context': 'https://schema.org',
7+
'@type': 'WebSite',
8+
name: 'GeoIP Locations',
9+
alternateName: 'ProdIPData',
10+
url: 'https://geoiplocations.com/',
11+
description:
12+
'Free GeoIP database downloads with monthly CSV, Parquet, and MMDB releases, ASN coverage data, and IPv4 geolocation insights from ProdIPData.',
13+
};
14+
---
15+
<BaseLayout
16+
title="Free GeoIP Database Downloads, ASN and Coverage Maps | ProdIPData"
17+
description="Download free GeoIP data from ProdIPData, including monthly CSV, Parquet, and MMDB releases, ASN intelligence, and country coverage summaries."
18+
canonicalPath="/"
19+
page="home"
20+
>
21+
<script slot="head" type="application/ld+json" is:inline set:html={JSON.stringify(website)} />
22+
23+
<main>
24+
<section class="hero">
25+
<div class="container hero-grid">
26+
<div class="hero-panel glass">
27+
<div class="eyebrow">GeoIP data and network intelligence by ProdIPData</div>
28+
<h1>GeoIP intelligence for coverage, routing, analytics, and operational insight.</h1>
29+
<p>
30+
Explore country, ASN, and regional registry views backed by the latest ProdIPData release. GeoIP Locations helps teams
31+
understand IP location, network ownership, and published footprint through downloadable files and browser-based views
32+
built for practical use.
33+
</p>
34+
<div class="actions">
35+
<a class="btn btn-primary" href="coverage.html">Explore Coverage</a>
36+
<a class="btn btn-secondary" href="downloads.html">Review Downloads</a>
37+
</div>
38+
<div class="data-note">All public website content, monthly release files, and technical reference catalogs on GeoIP Locations are provided totally free. Unless otherwise stated, published datasets and metadata are available under <a href="licensing.html">CC BY 4.0</a>.</div>
39+
<div class="stats-grid">
40+
<div class="stat-card">
41+
<strong data-home-stat="countries">243</strong>
42+
<span class="muted">Countries represented in the current ProdIPData release.</span>
43+
</div>
44+
<div class="stat-card">
45+
<strong data-home-stat="asns">128,753</strong>
46+
<span class="muted">Distinct ASNs represented in the current global footprint.</span>
47+
</div>
48+
<div class="stat-card">
49+
<strong data-home-stat="release" data-current-release>2026-04</strong>
50+
<span class="muted">Current published release month used across the website.</span>
51+
</div>
52+
</div>
53+
</div>
54+
<aside class="sidebar-panel glass">
55+
<h3>Current release availability</h3>
56+
<p class="card-text">
57+
ProdIPData publishes monthly datasets and downloadable files through a lightweight static website so teams can review the
58+
latest release quickly and integrate it into internal systems, applications, and workflows.
59+
</p>
60+
<div class="download-list" data-release-target></div>
61+
<div class="data-note">
62+
All public website content and downloadable files are provided totally free. Unless otherwise stated, published datasets and metadata are available under <a href="licensing.html">CC BY 4.0</a>. Use <a href="releases/index.html">the release archive</a> to navigate by month, use Coverage to explore countries and registries, or use Downloads to access CSV, Parquet, and MMDB files for local analysis.
63+
</div>
64+
</aside>
65+
</div>
66+
</section>
67+
68+
<section class="section">
69+
<div class="container">
70+
<div class="section-head">
71+
<div><h2>How GeoIP works</h2></div>
72+
<p>
73+
GeoIP links IP addresses to approximate geographic and network context. ProdIPData presents this information through
74+
country, ASN, and registry views that help users interpret coverage at a practical level.
75+
</p>
76+
</div>
77+
<div class="grid-3">
78+
<article class="section-card glass">
79+
<h3>IP address lookup</h3>
80+
<p class="card-text">An IP address can be associated with an approximate country, network, or published footprint so teams can understand where activity appears to originate and how it is represented in the release.</p>
81+
</article>
82+
<article class="section-card glass">
83+
<h3>Network and routing context</h3>
84+
<p class="card-text">GeoIP interpretation is strengthened by ASN, registry, and broader network context. ProdIPData complements location-oriented views with operator, footprint, and concentration signals.</p>
85+
</article>
86+
<article class="section-card glass">
87+
<h3>Accuracy depends on granularity</h3>
88+
<p class="card-text">Country-level interpretation is typically stronger than assumptions about exact city placement or precise coordinates. GeoIP works best when it is read as high-value context rather than perfect physical location.</p>
89+
</article>
90+
</div>
91+
</div>
92+
</section>
93+
94+
<section class="section">
95+
<div class="container">
96+
<div class="section-head">
97+
<div><h2>Why teams use ProdIPData</h2></div>
98+
<p>
99+
ProdIPData helps technical and business teams work from structured GeoIP files, browser-based views, and release-ready
100+
summaries that fit operational and analytical workflows.
101+
</p>
102+
</div>
103+
<div class="grid-3">
104+
<article class="section-card glass">
105+
<h3>Personalize local experiences</h3>
106+
<p class="card-text">Use country and network context to tailor content, reporting, and audience segmentation to the geographic footprint that matters to your organization.</p>
107+
</article>
108+
<article class="section-card glass">
109+
<h3>Analyze traffic and ownership</h3>
110+
<p class="card-text">Review country coverage, published prefixes, ASN concentration, and registry structure to understand how network presence is distributed across the internet footprint.</p>
111+
</article>
112+
<article class="section-card glass">
113+
<h3>Support operations and investigations</h3>
114+
<p class="card-text">Use downloadable files and web views to support routing reviews, internal enrichment workflows, exception analysis, and geolocation issue research.</p>
115+
</article>
116+
</div>
117+
</div>
118+
</section>
119+
120+
<section class="section">
121+
<div class="container">
122+
<div class="section-head">
123+
<div><h2>Intent-led data guides</h2></div>
124+
<p>
125+
Start with the page that matches the question you already have, whether that question is about GeoIP data,
126+
downloads, file formats, or country-level ASN structure.
127+
</p>
128+
</div>
129+
<div class="download-grid">
130+
<article class="section-card glass">
131+
<h3><a href="geoip-database.html">GeoIP database downloads</a></h3>
132+
<p class="card-text">Use this entry page when the main need is downloadable GeoIP files and local hosting workflows.</p>
133+
</article>
134+
<article class="section-card glass">
135+
<h3><a href="ip-geolocation-data.html">IP geolocation data</a></h3>
136+
<p class="card-text">Use this guide to understand what GeoIP data means and how country and network signals should be interpreted.</p>
137+
</article>
138+
<article class="section-card glass">
139+
<h3><a href="asn-data-by-country.html">ASN data by country</a></h3>
140+
<p class="card-text">Use this page for country-level operator structure, lead ASN share, and concentration questions.</p>
141+
</article>
142+
<article class="section-card glass">
143+
<h3><a href="geoip-csv-download.html">GeoIP CSV downloads</a></h3>
144+
<p class="card-text">Use this guide when the target workflow is spreadsheets, SQL imports, or simple operational ingestion.</p>
145+
</article>
146+
<article class="section-card glass">
147+
<h3><a href="geoip-parquet-download.html">GeoIP Parquet downloads</a></h3>
148+
<p class="card-text">Use this guide when the target workflow is analytics, Python, notebooks, or batch processing.</p>
149+
</article>
150+
</div>
151+
</div>
152+
</section>
153+
154+
<section class="section">
155+
<div class="container">
156+
<div class="section-head">
157+
<div><h2>Release archive and current month</h2></div>
158+
<p>
159+
ProdIPData is moving toward a release-oriented discovery path so users can move from global summaries to a month-specific release page and then into the CSV, Parquet, or MMDB package indexes that support local reuse.
160+
</p>
161+
</div>
162+
<div class="grid-3">
163+
<article class="section-card glass">
164+
<h3><a href="releases/index.html">GeoIP monthly release archive</a></h3>
165+
<p class="card-text">Browse the release archive when the goal is to understand what is available by month and which publication assets belong to each release.</p>
166+
</article>
167+
<article class="section-card glass">
168+
<h3><a href="releases/2026-04/index.html">Release 2026-04 overview</a></h3>
169+
<p class="card-text">Open the current release page for scope, package paths, methodology links, checksums guidance, and release-level notes.</p>
170+
</article>
171+
<article class="section-card glass">
172+
<h3><a href="downloads.html">GeoIP download indexes</a></h3>
173+
<p class="card-text">Go directly to the CSV, Parquet, and MMDB package indexes when the next step is download, local hosting, or workflow integration.</p>
174+
</article>
175+
</div>
176+
</div>
177+
</section>
178+
179+
<section class="section">
180+
<div class="container">
181+
<div class="section-head">
182+
<div><h2>Current release metrics</h2></div>
183+
<p>
184+
These headline metrics summarize the latest published GeoIP footprint, including country coverage, observed ASNs,
185+
active networks, and estimated IPv4 scale.
186+
</p>
187+
</div>
188+
<div class="metric-grid" data-metrics-target></div>
189+
</div>
190+
</section>
191+
192+
<section class="section">
193+
<div class="container grid-2">
194+
<div class="split-panel glass">
195+
<h3>Largest ASN footprints</h3>
196+
<p class="card-text">
197+
Leading networks in the current release by published /24 footprint, useful for quickly identifying the largest visible
198+
operators in the dataset.
199+
</p>
200+
<div class="download-list" data-home-biggest-target></div>
201+
</div>
202+
<div class="split-panel glass">
203+
<h3>Largest country footprints</h3>
204+
<p class="card-text">
205+
Countries with the largest published footprint in the current release, combining scale, coverage, and overall IPv4 presence.
206+
</p>
207+
<div class="download-list" data-home-country-target></div>
208+
</div>
209+
</div>
210+
</section>
211+
212+
<section class="section">
213+
<div class="container">
214+
<div class="section-head">
215+
<div><h2>New ASN additions in the current year</h2></div>
216+
<p>
217+
This section highlights recently added ASNs from the current year so visitors can track new network entries and the
218+
evolving shape of the published internet footprint.
219+
</p>
220+
</div>
221+
<div class="split-panel glass">
222+
<div class="download-list" data-home-new-asns-target></div>
223+
</div>
224+
</div>
225+
</section>
226+
227+
<section class="section" data-wave4-block="discovery-links">
228+
<div class="container">
229+
<div class="split-panel glass content">
230+
<h2>Explore deeper release and entity pages</h2>
231+
<p>
232+
The monthly release archive connects the current dataset to focused country, registry, and ASN pages. Use the <a href="releases/index.html">monthly release archive</a> for time-based navigation, open <a href="country/index.html">country profiles</a> for country-level footprint context, review <a href="rir/index.html">RIR pages</a> for registry-level coverage, and open <a href="asn/index.html">ASN profiles</a> for visible network entities in the current release. For package access, continue through <a href="downloads.html">GeoIP CSV, Parquet, and MMDB downloads</a>, and for source quality and caveats, review <a href="methodology.html">GeoIP methodology and validation</a>.
233+
</p>
234+
</div>
235+
</div>
236+
</section>
237+
</main>
238+
</BaseLayout>

0 commit comments

Comments
 (0)