Vue 3 + TypeScript single-page app for VocabPluse — flashcard-based English vocabulary learning with AI explanations, progress tracking, Google login, and subscription plans.
This repository contains the frontend only. It talks to the VocabPluse Django REST API.
- Browse GRE words and Other words by Easy / Medium / Hard / Advanced.
- Study a set as shuffled flashcards: Define, Explanation with AI, Example Questions.
- Google (Gmail) sign-in; JWT stored locally, with automatic refresh.
- Account page with subscription status and progress.
- Plans / checkout (backend handles SSLCommerz or a mock payment in local dev).
Access rules are enforced by the API:
| User | Browse | Define | AI explanation | Example questions | Progress |
|---|---|---|---|---|---|
| Anonymous | Easy + Medium | Yes | 10 demo words | No | No |
| Logged-in (free) | Easy + Medium | Yes | 40 total | No | Yes |
| Subscriber | All levels | Yes | Unlimited | Yes | Yes |
- Vue 3 with Composition API (
<script setup>) - TypeScript
- Vite 5 (Node 18.18+ compatible)
- Pinia for state
- Vue Router for navigation
- Axios for API calls (JWT request header + refresh interceptor)
- Node.js 18.18+ (Node 20+ recommended)
- A running VocabPluse backend (default:
http://localhost:8000/api)
npm install
cp .env.example .env # set VITE_API_BASE and VITE_GOOGLE_CLIENT_ID
npm run devOpen http://localhost:5173.
Restart npm run dev after any change to .env. Vite only reads VITE_* variables at startup.
| Command | Description |
|---|---|
npm run dev |
Start Vite dev server (port 5173) |
npm run build |
Type-check and produce production build in dist/ |
npm run preview |
Preview the production build locally |
| Variable | Purpose |
|---|---|
VITE_API_BASE |
Backend API base URL (e.g. http://localhost:8000/api) |
VITE_GOOGLE_CLIENT_ID |
Google OAuth Web client ID. The login button is hidden when empty. |
VITE_GOOGLE_CLIENT_ID must be the same value as GOOGLE_OAUTH_CLIENT_ID on the backend.
- Create a Web application OAuth client in Google Auth Platform → Clients.
- Authorized JavaScript origins (no trailing slash):
http://localhost:5173http://127.0.0.1:5173
- Authorized redirect URIs:
http://localhost:5173/login - Paste the Client ID into
.envasVITE_GOOGLE_CLIENT_ID. - Add your Gmail as a test user on the OAuth consent / Audience screen.
- Restart
npm run dev.
The page loads Google Identity Services, receives an ID token, and posts it to POST /api/auth/google/. You do not put the Google client secret in this repo.
For production, add https://vocabpluse.com as a JavaScript origin and rebuild with the production VITE_API_BASE.
.
public/ Static assets (favicon)
src/
api/ Axios client, auth header, token refresh
components/ NavBar, FlashCard
router/ Route definitions
stores/ Pinia stores (auth, catalog)
views/ Home, Set, Login, Account, Plans
utils/ Helpers (e.g. markdown)
App.vue Root layout
main.ts App bootstrap
types.ts Shared TypeScript types
.env.example
| Route | View | Description |
|---|---|---|
/ |
Home | Browse categories and word sets |
/sets/:id |
Set | Flashcard study session |
/login |
Login | Google sign-in |
/plans |
Plans | Subscription plans and checkout |
/account |
Account | Profile and progress |
npm run buildServe the dist/ folder with any static file host or reverse proxy (e.g. Nginx). Set VITE_API_BASE to the production API before building.
VITE_GOOGLE_CLIENT_ID is empty. Set it in .env and restart Vite.
The Client ID is wrong or JavaScript origins do not include http://localhost:5173. Copy the ID from Google Cloud (do not type it). flowName=GeneralOAuthFlow is Google’s normal login flow, not a VocabPluse setting.
The frontend Client ID does not match the backend GOOGLE_OAUTH_CLIENT_ID, or one of the servers was not restarted after .env was updated.
This project uses Vite 5, which supports Node 18.18+:
node --versionIf npm run dev fails after switching Node versions:
rm -rf node_modules package-lock.json
npm installConfirm the backend is running and VITE_API_BASE matches the API URL, including the /api suffix.
Vite defaults to 5173. If that port is taken it may start on 5174, which is not in the backend CORS list or Google origins. Free port 5173 or add the new origin in both places.