EduMap Banyumas
EduMap Banyumas maps school and district data for Banyumas Regency. Built as a rebuild of an existing GIS app, it gives the public a filterable map and searchable tables, while admins get a full dashboard for managing districts, schools, and users.

- My part
- Design & Full Stack Development
- Updated
- November 1, 2026
- Reading time
- 3 min read
EduMap Banyumas
EduMap Banyumas started as a rebuild of an existing GIS app for education data in Banyumas Regency. The older version had the core idea right: show schools and districts on a map, let admins manage the data behind it. I rebuilt it from Laravel 11, Bootstrap 5, and MySQL into a Next.js 16 App Router project so the codebase would be easier to maintain, stricter about data shape, and more suitable for my portfolio.
The Problem
School data has a spatial side that a plain table does not show well. You can search for a school by name or NPSN, but it is harder to understand how schools are spread across districts without seeing them on a map. Admins also need one place to manage districts and schools — with validation, authentication, image uploads, and clear feedback when something changes.
The tricky part was the map. React Leaflet does not play nicely with server-side rendering, and Next.js 16 App Router has its own conventions that differ from older Next.js patterns. I had to be careful about what belonged on the server and what had to stay client-only.
Building It
I started with the data model. Prisma stores regencies, districts, schools, users, sessions, passkeys, and rate limits in PostgreSQL. District geometry is stored as JSONB instead of PostGIS — this project needs mapping and CRUD more than heavy spatial analysis, so keeping the Neon setup simple made more sense.
The public map is built as a full-screen experience. The page fetches basic stats on the server: district count, school count, public schools, private schools. Leaflet components load through dynamic imports with SSR disabled. District polygons come from /api/kecamatan, with geometry simplified before it reaches the browser.
School markers load from based on map bounds, zoom level, district, school level, status, and search query. The seed data has 1,079 schools — loading all of them at once would technically work, but the map waits until the user zooms in, then requests only what's visible in the current viewport.


