Skip to content

Latest commit

 

History

History
131 lines (98 loc) · 5.8 KB

SELF-HOSTING.md

File metadata and controls

131 lines (98 loc) · 5.8 KB

Self-hosting StudyMap

Run StudyMap for your own city. Everything below works from a fork, no coding required beyond editing one config file and your place data.

What you get out of the box

  • The interactive map, filters, search, and calendar for whatever data/places/*.json you provide.
  • Two optional, signed-in-only features (saved places, personal calendar events) if you set up your own Supabase project. Skip that section entirely and the app still works, just without those.

1. Get the code

Click "Use this template" at the top of StudentSuite/StudyMap to create your own copy, then clone it:

git clone https://github.com/<your-account>/<your-fork>.git
cd <your-fork>
npm install

2. Set your region and dataset

Everything region- and data-specific lives in one file: studymap.config.ts at the repo root.

cp studymap.config.example.ts studymap.config.ts

Edit it:

  • center: [lat, lng] for the initial map view
  • defaultZoom: initial zoom level (11-13 works well for a metro area)
  • cities: preferred display order for the city filter — a hint, not an exhaustive list (any city present in your data but missing here still shows, just sorted alphabetically after)
  • places: swap the sample imports for your own data/places/*.json files
  • competitions: swap the data/competitions/*.json imports for your own, or set it to [] if you don't want a competitions catalog (the competitions pages then show an empty list). The record shape is in data/competitions/CONTRIBUTING.md

The dataset itself follows the schema in data/CONTRIBUTING.md: one JSON file per place type, one object per place, with id, name, type, city, lat, lng, gmaps_link, and added_by. data/places.sample/ has two minimal example entries if you want to start from a clean skeleton instead of the Mumbai dataset that ships with the template.

Validate as you go:

npm run validate

3. Environment variables

cp .env.example .env.local
  • NEXT_PUBLIC_MAPTILER_KEY is required for the map basemap. Free tier, no credit card, at cloud.maptiler.com.
  • If the key is missing or empty, the map shows "Basemap unavailable" instead of loading tiles. Add the key to .env.local, then restart the development server or redeploy the site.
  • The Supabase variables are optional. Leave them blank and the map, filters, and calendar all work; you just won't get sign-in or the two private features below. See step 5 to fill them in.

4. Run it

npm run dev

Open http://localhost:3000/map and confirm your places show up in the right spot.

5. Optional: sign-in, saved places, personal calendar events, saved competitions, and onboarding

These features (src/app/login, saved custom places, personal calendar events, saved competitions, the first-run onboarding questionnaire, the saved-competitions calendar feed) need a Supabase project:

  1. Create a free project at supabase.com.
  2. Copy its URL and anon key into .env.local (NEXT_PUBLIC_SUPABASE_URL, NEXT_PUBLIC_SUPABASE_ANON_KEY).
  3. In the Supabase SQL editor, run every file in supabase/migrations/, in filename order. Each one creates its tables with row-level security already scoped to auth.uid(), so users can only ever read or write their own rows. This includes user_places, user_home, and user_events (the three original sign-in-gated tables), plus competition_saves and competition_stats for the competitions vertical: saves are private per user, and competition_stats is a public save-count aggregate kept in sync by a trigger, readable by anyone but writable only by that trigger, never directly. It also includes user_profiles, one row per user holding their answers to the first-run onboarding questionnaire (graduation year, board, field, country, referral source), all columns nullable since the questionnaire is skippable and resumable, and owner-only RLS so nobody but the user (or the dashboard's service-role SQL editor) can read their answers. user_profiles.calendar_token (a later migration) is the opaque bearer token behind GET /api/competitions/saved.ics?token=..., the saved-competitions calendar subscription feed: that route authenticates itself with the token via a security definer SQL function rather than a signed-in session, since a calendar app fetching the feed carries no cookies at all.
  4. Enable whichever auth providers you want (email, Google, etc.) under Authentication > Providers.

Skip this whole section if you only want the public map and calendar.

6. Deploy

Deploy like any standard Next.js app, for example on Vercel:

npx vercel

or import the repo at vercel.com/new and set the same environment variables from step 3 in the project settings.

Static export (output: "export") is not supported. Sign-in needs a live server: the OAuth callback route exchanges a code for a session server-side, and middleware refreshes that session on every request. Both are incompatible with a static build. Deploy to a normal server/edge runtime instead, that's the default for Vercel and most other Next.js hosts.

Keeping your fork current

StudyMap doesn't push updates to forks automatically. To pull in upstream fixes, add the original repo as a remote and merge from it:

git remote add upstream https://github.com/StudentSuite/StudyMap.git
git fetch upstream
git merge upstream/main

Your studymap.config.ts, .env.local, and data/places/*.json are yours, upstream changes to shared code (map, calendar, components) merge in without touching them, unless you've also edited those files.