Rječnik is a Bosnian language dictionary application. This is a monorepo containing:
rjecnik-web— public-facing dictionary search site (Vercel)rjecnik-admin— admin dashboard for managing entries (Netlify)rjecnik-etl— one-time Python ETL pipeline (historical use, not actively developed)supabase— migrations, edge functions, and local dev config shared by both apps
See docs/CONTRIBUTING.md for contribution guidelines, and docs/architecture/decisions for the architecture decision records behind these choices.
- Node 20+ (see each app's
.nvmrc, or runnvm usefrom withinrjecnik-web/rjecnik-admin) - Supabase CLI
- Docker
- Navigate to
rjecnik-weband/orrjecnik-admin:
cd rjecnik-webcd rjecnik-admin- Install npm packages:
npm install- Configure the application:
cp .env.example .envrjecnik-webonly:NEXT_PUBLIC_GITHUB_REPOSITORYis the full URL of the GitHub repo (e.g.https://github.com/OpenSourceSarajevo/rjecnik), used to build the "report an issue" link on each dictionary entry.rjecnik-adminonly:NEXT_PUBLIC_SITE_URLis the base URL Google OAuth redirects back to after sign-in (${NEXT_PUBLIC_SITE_URL}/auth/callback). Defaults tohttp://localhost:3000for local dev — change it to your deployed/preview URL when testing auth on Netlify.
- Run the application:
npm run devOpen http://localhost:3000 with your browser to see the result. Make sure to configure a different port for one of the apps if running both.
-
Set up a Google Cloud Console app to get a client id and secret:
- Go to the Google Cloud Console credentials page and create an OAuth 2.0 Client ID (Web application type).
- Add an Authorized redirect URI:
- Local Supabase (via Docker):
http://localhost:54321/auth/v1/callback - Hosted Supabase:
https://<your-project-ref>.supabase.co/auth/v1/callback(find the exact value in your Supabase dashboard under Authentication → Providers → Google)
- Local Supabase (via Docker):
- Copy the generated Client ID and Client Secret — you'll need them in the next step.
-
If you are using supabase via docker, follow the steps for setting the environment variables correctly, and if you are using a hosted instance of supabase follow the official supabase docs for setting up auth providers
-
Try signing in via google, this will add your email to the database but fail
-
Manually assign the
app_permissionDictionary.ReadWriteto your user in theuser_permissionstable, then try signing in again:-
Via Supabase Studio (local instance at http://localhost:54323): open Table Editor →
user_permissions→ insert a new row with youruser_id(find it in theauth.userstable) andpermissionset toDictionary.ReadWrite. -
Via SQL Editor (Studio or hosted dashboard), replacing
<your_user_id>:insert into user_permissions (user_id, permission) values ('<your_user_id>', 'Dictionary.ReadWrite');
-
-
Start docker desktop
-
Export google cloud console secrets:
export AUTH_GOOGLE_CLIENT_ID=
export AUTH_GOOGLE_CLIENT_SECRET=
- Start the supabase container:
supabase start-
From the console output copy the values of
API URLandanon keyinto your app's.env:rjecnik-web:SUPABASE_URLandSUPABASE_ANON_KEYrjecnik-admin:NEXT_PUBLIC_SUPABASE_URLandNEXT_PUBLIC_SUPABASE_ANON_KEY
-
Stop the container
supabase stopsupabase stop --no-backup- To create a new migration for the supabase database run:
supabase migration new <migration_name>-
Navigate to
supabase/migrations, find your new migration file and write you SQL. -
Apply the new migration by restarting the supabase container
supabase startfails immediately / hangs with a connection error. Make sure Docker Desktop is running first — the Supabase CLI needs it to pull and run the local Postgres/Auth/Studio containers.supabase starttakes several minutes the first time. This is expected — it's pulling the Supabase Docker images. Subsequent starts are much faster since the images are cached.- Port
3000already in use when running both apps. Bothrjecnik-webandrjecnik-admindefault to port 3000. Run one of them on a different port:npm run dev -- -p 3001. - Signed in with Google but still can't access the admin dashboard. You're missing the
Dictionary.ReadWritepermission — see step 4 of Setting up auth above.