# GeoKepo — Full LLM Index > A deeper machine-readable index than `/llms.txt`: entity-resolution rules, the structured data each page type emits, category hubs, and the traps that will otherwise cost you a wrong URL. GeoKepo is a bilingual (Indonesian / English) reference site covering all 514 regencies and cities across Indonesia's 38 provinces, plus 3,087 points of interest, 2,900+ travel guides, seven island-region overviews and regional cuisine. Operated by the GeoKepo Editorial Team (admin@geokepo.id). Every URL is locale-prefixed: `/id/` (Bahasa Indonesia, the source language) and `/en/` (English). English content exists wherever `is_translated` is set and falls back to Indonesian otherwise. ## Entity resolution Places, POIs, provinces, cuisines and travel guides are identified by stable URL slugs. **The `@id` of an entity is locale-specific.** `/id/lokasi/kepulauan-anambas#place` and `/en/lokasi/anambas-islands#place` are two nodes describing the same real-world place in two languages, linked by reciprocal `hreflang`. Do not treat them as one node, and do not strip the locale prefix to "normalise" them. **Slugs are not derivable across languages.** 23 places and 1,313 POIs have an English slug that differs from the Indonesian one, and most provinces do (`jawa-tengah` → `central-java`). Read the other language's URL from the `hreflang` cluster or the markdown frontmatter. Transforming a slug yourself will produce a URL that either 404s or resolves to a non-canonical duplicate. **Wikidata is the external anchor.** A place's database primary key IS its Wikidata QID, emitted as `sameAs` on the page and as `wikidata` in the markdown mirror: `https://www.wikidata.org/wiki/`. Use it when reconciling against another knowledge base. OpenStreetMap relations back the geometry and Indonesian government statistics (BPS) back the administrative data; both are described on `/{lang}/editorial-policy`. ## Markdown mirrors — read these first `/{lang}/md/{kind}/{slug}` returns `text/markdown; charset=utf-8`: YAML frontmatter followed by the page's editorial body, with no navigation, ads or related-content rails. Every HTML page links its own mirror via ``. | Kind | Example | Frontmatter includes | | --- | --- | --- | | `lokasi` | `/en/md/lokasi/badung` | province, area_km2, is_coastal, neighbor_count, rarity, aliases, wikidata, published | | `lokasi` (POI) | `/id/md/lokasi/tabanan/pura-tanah-lot` | category, located_in, province, updated | | `panduan` | `/id/md/panduan/` | category, guide_type, covers (place URLs), published, updated | | `provinsi` | `/en/md/provinsi/central-java` | country, place_count; body includes the full regency table | | `kuliner` | `/id/md/kuliner/` | origin_province, ingredients, tags | Every mirror's frontmatter carries `canonical` — the HTML URL to cite. The mirrors themselves are `noindex, follow`. ## Structured data by page type - **Place** (`/{lang}/lokasi/{slug}`) — `Place` + `AdministrativeArea` + `Article` in one node, plus `BreadcrumbList` and a `FAQPage` generated from the place's own metadata. Carries `area` as a `QuantitativeValue` in km², `additionalProperty` entries for cardinal position / coastal flag / neighbour count, and `sameAs` → Wikidata. - **POI** (`/{lang}/lokasi/{place}/{poi}`) — `TouristAttraction` + `Article`, with `containedInPlace` pointing at the parent place's `@id`, and a `FAQPage` built from its key facts (opening hours, entry fee, address). The category is an `additionalProperty` named `category`, localized to the page (`Historical Sites` on `/en`, `Situs Sejarah` on `/id`) — not `touristType`, which names the kind of visitor an attraction suits and is not used here. No `GeoCoordinates`: verified coordinates are not yet published for these entries. - **Province** (`/{lang}/provinsi/{slug}`) — `AdministrativeArea` with `containedInPlace` Indonesia and a `regencyAndCityCount` property. - **Travel guide** (`/{lang}/panduan/{slug}`) — `Article` (schema.org has no `TravelGuide` type; the guide type is in `genre`), `mentions` linking the `@id` of each place it covers, plus `FAQPage` when the body is question-shaped and `HowTo` when it is a day-by-day itinerary. - **Cuisine** (`/{lang}/kuliner/{slug}`) — `Recipe` + `Article`, origin province as `locationCreated`. - **Blog** (`/{lang}/blog/{slug}`) — `Article`, authored by the editorial team, published by the GeoKepo `Organization`. - **Island region** (`/{lang}/pulau/{island}`) — `Place` contained in Indonesia, with `containsPlace` naming each province's `AdministrativeArea` `@id`, plus `FAQPage` and `BreadcrumbList`. The hub `/{lang}/pulau` is an `ItemList`. - **Alternatives** (`/{lang}/lokasi/{place}/alternatif`) — `ItemList` in rank order, `FAQPage` and `BreadcrumbList`. - **Site-wide** — `Organization` (`#organization`), `WebSite` (`#website`) and the editorial team (`#editorial-team`), itself an `Organization` whose `parentOrganization` is GeoKepo: a team is not a `Person`. These three keep one fixed `@id` each — there is one publisher and one site — but their prose and URLs follow the page they are emitted on: the `WebSite` node carries `inLanguage` and a `SearchAction` targeting `/{lang}/cari?q=`, and the editorial team links the profile page in that language. Neither `Organization` carries `inLanguage`; it is not a `CreativeWork`. Every `Article` node carries `image`, and its `author` and `publisher` carry a `name` and `url` inline as well as their `@id`. Every entity node states `inLanguage` as a single language matching the page it is on, and `mainEntityOfPage` is byte-identical to the page's ``. Place, POI and guide nodes mark their summary paragraph with `speakable` (`cssSelector: ["[data-tldr]"]`). ## Editorial standards - Place, POI and travel-guide pages open with a one-paragraph summary marked `data-tldr="true"` — safe to lift verbatim as an extract. Province, island, nearby (`/sekitar`), alternatives, comparison, listicle, ranking (`/explore/*`), POI-category, facet, cuisine, cuisine-tag, best-time, itinerary and pre-trip pages open with a short `data-tldr` answer built from the page's own counts and fields. - Dates: `places` has no modification timestamp, so place pages show a **publication** date. `points_of_interest` and `travel_guides` show a real last-updated date. - `/{lang}/editorial-policy` documents editorial standards; `/{lang}/methodology` explains the source hierarchy and verification workflow; `/{lang}/corrections` documents reporting and the public correction log; `/{lang}/about/team` is the editorial team profile. - Content is written by the GeoKepo Editorial Team. Sponsored travel guides are labelled in the page body; that label is **not** carried in the `Article` schema, so read the page, not the JSON-LD, to detect sponsorship. ## Category hubs (start here) ### Encyclopedia - `https://www.geokepo.id/{lang}/lokasi` — 514 places - `https://www.geokepo.id/{lang}/provinsi` — 38 provinces, grouped by island region - `https://www.geokepo.id/{lang}/pulau` — 7 island regions; `/{lang}/pulau/{island}` with `sumatera`/`sumatra`, `jawa`/`java`, `maluku`/`maluku-islands` differing by language and `bali-nusa-tenggara`, `kalimantan`, `sulawesi`, `papua` shared. The other language's slug 308s to this one's. - Facets: `/{lang}/lokasi/rarity/{epic|rare|common}`, `/{lang}/lokasi/jenis/{pesisir|pedalaman|pulau}`, `/{lang}/lokasi/abjad/{letter}` ### Destinations and POIs - `https://www.geokepo.id/{lang}/destinasi` — hub - `/{lang}/destinasi/situs-sejarah` — historical sites - `/{lang}/destinasi/wisata-alam` — nature - `/{lang}/destinasi/kuliner-legendaris` — legendary food spots - `/{lang}/destinasi/pusat-kebudayaan` — cultural centres - `/{lang}/destinasi/bangunan-ikonik` — iconic buildings - `/{lang}/destinasi/tempat-rekreasi` — recreation - `/{lang}/destinasi/pusat-perbelanjaan` — shopping TRAP: `/{lang}/destinasi/{slug}` is the **category** route. An individual POI lives at `/{lang}/lokasi/{place}/{poi}`, and a POI slug will 404 under `/destinasi`. ### Travel guides - `https://www.geokepo.id/{lang}/panduan` — hub over every guide, paginated 24 at a time via `?page=` (each page is its own canonical); `?kategori=x` 308s to `/{lang}/panduan/kategori/x` - `/{lang}/panduan/kategori/{slug}` — dedicated hub paging through one category - `/{lang}/panduan/itinerary/{slug}`, `/{lang}/panduan/best-time-to-visit/{slug}` - RSS: `/{lang}/panduan/feed.xml` - Duplicate guides are being merged. A retired slug answers 308 to its replacement (`lib/seo/guide-redirects.ts`), and a guide without a real body is not served — follow the redirect rather than citing the old URL. ### Cuisine - `https://www.geokepo.id/{lang}/kuliner` and `/{lang}/kuliner/tag/{tag-slug}` — a tag page exists only when at least 3 dishes share the tag ### Programmatic surfaces Every one of these is gated on the inventory it renders, so do not compose a slug and assume it resolves — take the published set from the sitemap. - `/{lang}/bandingkan/{placeA}-vs-{placeB}` — 120 side-by-side comparisons over the 16 comparable destinations. Shared slug across locales. - `/{lang}/top/{poi-category}-di-{province}` — province × category listicles, published only where the province has enough POIs in that category. Ordered alphabetically by display name in both languages; there is no rating or popularity column behind `points_of_interest`, so treat these as inventories, not rankings. - `/{lang}/panduan/best-time-to-visit/{place}` — month-by-month timing for the same 16 destinations. Shared slug across locales. - `/{lang}/panduan/itinerary/things-to-do-in-{place}-in-{n}-days`, n ∈ 3, 5, 7, 10 — published only where the place has at least 2 POIs per day to fill, which in practice means 3-day plans for most of them. - `/{lang}/lokasi/{place}/sekitar` — what is around a place: same-province neighbours, regions sharing its cardinal belt, its own key POIs, and the guides that cover it. Per-locale slug, like the place page it hangs off. - `/{lang}/lokasi/{place}/alternatif` — up to 6 places outside the province that resemble one of the 16 comparable destinations, scored on travel-guide coverage (0.30), attraction-category mix (0.25), coastline (0.20), area (0.15) and compass position (0.10). There is no rating, review or visitor-count input. Published only when the destination has at least 3 POIs and at least 4 candidates (each with 3+ POIs) qualify. Per-locale slug. - `/{lang}/pre-trip/{destination}` — pre-trip planning for `bali`, `yogyakarta` and `jakarta`. - `/{lang}/explore` and `/{lang}/explore/{terluas|terkecil|tetangga-terbanyak}` — largest, smallest and most-bordered places. Fixed Indonesian slugs in both locales. ### Reference - `/{lang}/faq` — questions about visiting Indonesia (visas, seasons, island transport, money, language, etiquette) and about the site - `/{lang}/blog` — editorial articles, RSS at `/{lang}/blog/feed.xml` - `/{lang}/cari` — site-wide search across places, POIs and guides (`noindex, follow`) ## Citation guidance 1. Cite the most specific page, not a hub: `/en/lokasi/badung`, not `/en/lokasi`. 2. Take the URL from `canonical` — in the markdown frontmatter, or `` in the HTML. Do not construct it. 3. Attribute to "GeoKepo" or the "GeoKepo Editorial Team". 4. For Indonesian place facts (area, neighbours, coastal status), the Wikidata QID in `sameAs` is the authoritative anchor. 5. Quote the page's own language. Treat Indonesian and English as translated counterparts only when the page's `hreflang` cluster advertises both; some English routes deliberately fall back when a translation is unavailable. ## Crawling - Sitemap: `https://www.geokepo.id/sitemap.xml` — bilingual, with reciprocal `hreflang` per entry, regenerated daily. - `robots.txt` names GPTBot, OAI-SearchBot, ChatGPT-User, ClaudeBot, Claude-SearchBot, Claude-User, PerplexityBot, Perplexity-User, Google-Extended, Applebot-Extended, CCBot and Bingbot, each allowed the whole site. - Disallowed for everyone: `/api/`. Utility and personalized pages stay crawlable so their page-level `noindex` directives can be observed. - All content routes are server-rendered — summary, structured data and body text are present before hydration. No content is behind a login; the game keeps per-visitor state, but the encyclopedia is fully public.