01 — Local development setup¶
This document walks a new developer from a fresh clone to a running app on their machine.
Prerequisites¶
- Node.js 20.x (the production image uses
node:20.18.3-slim; matching this avoids native-module surprises). There is no.nvmrc/.tool-versions/enginespin in this repo, so version managers likenvm,fnm, orvoltawon't auto-switch you to the right version — set it yourself before runningyarn install. Verify withnode --versionbefore continuing. - Yarn 1.x (classic). The repo uses
yarn.lock; do not runnpm install— it will produce a different dependency tree. Verify withyarn --version(should print1.x). Newer Yarn 2/3/4 (Berry) is incompatible with this lockfile format. - A working backend to point at. The frontend has no embedded backend; you must point
API_URLat a running Someli API instance (dev/UAT/prod, depending on what you have access to). Verify with the team which backend URL to use for local development. - Vue 2 DevTools browser extension. The Vue 3 DevTools does not work correctly with Vue 2.7 — install the legacy v6.x version explicitly. Without it, debugging components and Vuex state is significantly harder.
- A code editor that respects
.editorconfig. Most modern editors do automatically; the project enforces 2-space indent, LF line endings, UTF-8, and trim-trailing-whitespace. - (Optional but recommended) VS Code with the Vetur extension for Vue 2. Do not install Volar — Volar is the Vue 3 successor and does not understand
.vuefiles in this codebase.
Get the code¶
Clone from GitHub:
The repo URL above is the one referenced in Jenkinsfile. Verify with the team if you need a different fork or a different remote.
Initial branch. The Jenkins pipeline deploys from dev_app; engineers branch off dev_app for feature work. After cloning, check out the branch the team is currently developing against (most likely dev_app):
main and uat_app exist but are merge-only branches (see 20-contributing.md). Don't develop on them.
Disk space. Plan for ~1.5 GB of node_modules once everything is installed (~840 MB at the repo root, ~600 MB inside polotno-editor/), plus the build artifacts. SSDs are strongly recommended — file-watching across node_modules is the slowest part of yarn dev startup.
First-time setup¶
The repo contains two Node projects with separate node_modules and lockfiles:
- The Nuxt app at the repo root.
- The Polotno editor at
polotno-editor/.
Install both:
Editor / IDE config¶
A few things in this repo will surprise you if you don't read them ahead of time:
.vscode/settings.jsondisables format-on-save, format-on-paste, and format-on-type. If you have global Prettier-on-save in VS Code, it will be silently overridden when you open this repo. The project relies on the explicityarn formatcommand (Prettier, run on demand) instead. Don't override the workspace setting unless the team agrees..editorconfigis honored automatically by most editors. It enforces 2-space indent, LF line endings, UTF-8, and trim-trailing-whitespace (except in Markdown). If you're on Windows and your editor inserts CRLF, fix that — the build is LF-only.- No pre-commit hooks. No
husky, nolint-staged, nosimple-git-hooks. Nothing runs automatically when you commit. Type-check / format / sanity-check is your responsibility. - No
.env.example— there should be one, but there isn't. UseDockerfile'sARGdeclarations as the canonical list (or the table below) and create your own.env.
Environment variables¶
The app reads env vars from a .env file at the repo root via @nuxtjs/dotenv (registered in nuxt.config.js under buildModules). The Polotno editor reads its own .env from polotno-editor/.env.
Both .env and polotno-editor/.env (and .env.test) are already covered by .gitignore, so accidental commits are unlikely. Watch out for editor backup files like .env~ (vim's swap-style backup) — these are not gitignored and have leaked into the working tree before. Delete any .env~ you find.
The complete list of variables consumed by the production build is in Dockerfile (search for ARG). At minimum you will need values for:
Root .env (Nuxt app)¶
| Variable | Used for |
|---|---|
API_URL |
Backend base URL — set as axios.baseURL in nuxt.config.js. |
APP_URL |
Public URL of the frontend itself (used for OAuth callbacks). |
APP_TYPE |
Sent as a base64 apptype header on every request — see middleware/axios.js. |
FACEBOOK_CLIENT_ID |
Facebook OAuth. |
FACEBOOK_CLIENT_SECRET |
Facebook OAuth. |
TWITTER_CUSTOMER_KEY |
Twitter OAuth (legacy/v1). |
TWITTER_CUSTOMER_SECRET |
Twitter OAuth (legacy/v1). |
TWITTER_CLIENT_ID |
Twitter OAuth 2.0. |
TWITTER_CLIENT_SECRET |
Twitter OAuth 2.0. |
EXPRESS_SECRET |
Express session secret (referenced by commented-out passport setup; verify whether still required). |
STRIPE_PUBLIC_KEY_TEST |
Stripe (test mode). |
STRIPE_PUBLIC_KEY_LIVE |
Stripe (live mode). |
PADDLE_CLIENT_TOKEN |
Paddle billing. |
PADDLE_ENV |
Paddle environment selector (live/sandbox). |
PADDLE_TEST_CLIENT_TOKEN |
Paddle sandbox token. |
PADDLE_TEST_ENV |
Paddle sandbox environment. |
YOUTUBE_API_KEY |
YouTube Data API key (used by the /api/youtube-videos server middleware). |
YOUTUBE_CHANNEL_ID |
YouTube channel ID. |
GOOGLE_API_KEY |
Google API key (general). |
CRM_CHAT_ID |
CRM chat widget ID. |
CHASKIQ_KEY |
Chaskiq support widget key. |
CHASKIQ_DOMAIN |
Chaskiq domain. |
CRM_webhook_url |
CRM webhook URL. |
CAMPAIGN_ID |
Marketing campaign ID. |
REACT_APP_BASE_URL |
Used by the Polotno bundle (passed through both builds). |
GTM_ID |
Google Tag Manager (defaults to GTM-KBZLX362 in nuxt.config.js if unset). |
CLARITY_PROJECT_ID |
Microsoft Clarity (defaults to u1v818dob2 in nuxt.config.js if unset). |
Polotno .env (editor sub-project)¶
| Variable | Used for |
|---|---|
REACT_APP_BASE_URL |
Backend base URL the editor calls. |
GEMINI_AI_KEY, PROJECT_ID, LANGUAGE_MODEL, VERTEX_ACCESS_TOKEN |
Google Gemini / Vertex AI for AI text/image features. |
STABILITY_AI |
Stability AI key for image generation. |
LEONARDO_AI |
Leonardo AI key for image generation. |
Verify with the team which of these are required for the local-dev happy path versus optional. Several features will degrade gracefully without their key, but it is not always obvious which ones.
What about secrets?¶
Don't commit .env files. .gitignore already covers .env, .env.test, and polotno-editor/.env, but always glance at git status before committing — and especially watch for editor backup files (.env~, .env.bak, etc.) which are not gitignored. The CI pipeline injects values via Docker --build-arg (see Dockerfile).
Daily commands¶
# Nuxt dev server with HMR — listens on http://localhost:3000
yarn dev
# Production build (writes to .nuxt/)
yarn build
# Serve a production build (also localhost:3000)
yarn start
# Static-site generation
yarn generate
# Format pages/, components/, layouts/, helpers/ with Prettier
yarn format
The dev server binds to :3000 by default (Nuxt 2's standard port). Override with HOST=0.0.0.0 PORT=4000 yarn dev if you need to.
There is no test script and no lint script in package.json. ESLint config is present (under the eslintConfig key) but not wired to a script — the team relies on Prettier and manual review. There are also no Git hooks (no husky, no lint-staged); nothing runs automatically when you commit. Verify with the team before assuming any of this exists somewhere unconventional.
Working on the Polotno editor¶
The Nuxt app does not load the editor's source at runtime. It imports a prebuilt bundle at the repo root (polotno-bundle.js/polotno-bundle.css). Editor pages contain literal import { createEditor } from '../../../../polotno-bundle' — the path is relative to polotno-editor/'s build output.
The standalone editor is also runnable on its own:
To see editor changes inside the Nuxt app, you must rebuild the bundle:
Then refresh the Nuxt app. There is no watcher that does this automatically; it is a manual two-step.
Verify your setup¶
Once yarn dev starts successfully, you should see something like:
Open http://localhost:3000/ in your browser. A correctly configured setup shows the Someli login page (pages/index.vue — Someli logo header, social-login tabs, email/password form). If you see this, your toolchain is good.
Quick sanity checks if anything looks off:
- Page loads but no styles. Bootstrap 5 / FontAwesome / Slick / fonts come from CDNs declared in
nuxt.config.js → head.link. If your network blocks CDNs, expect broken layout. - Login form posts but nothing happens. Open devtools → Network and confirm
POST <API_URL>/webauthenticate. If the request goes tolocalhost:3000/webauthenticate, your.envAPI_URLis empty — restartyarn devafter fixing. Vue.config.devtoolswarning in console. Confirms Vue 2 DevTools is missing; install it.- Vuex visible in devtools. Open Vue DevTools → Vuex tab. You should see modules
api,post,dashboard,chat,leaderboard,plan,reach,common,onboarding. If empty, Vue DevTools is the wrong version. - Polotno bundle missing. If the editor route loads but the canvas is blank, check that
polotno-bundle.jsandpolotno-bundle.cssexist at the repo root. If not, runcd polotno-editor && yarn build.
To verify a logged-in flow end-to-end you'll need test credentials — ask the team. After login, you should land at /<accountId>/contentplanner (or wherever your test account's landing_url points; see 03-auth-and-sessions.md).
Common first-day issues¶
baseURLis undefined.API_URLnot set in.env, or your Nuxt server was started before you created.env. Restartyarn devafter editing.env.- CORS errors against the backend. The backend probably needs to allow your local origin. Talk to the backend team.
- Cookies not being set in dev. The auth strategy uses
sameSite: 'none'; secure: true(seenuxt.config.js,auth.cookie.options). Plainhttp://localhostcookies fail to set undersecure: true. The most common workaround ismkcertfor a locally-trusted cert:Then run Nuxt behind a proxy (Caddy, nginx, orbrew install mkcert nss # macOS; on Linux use your package manager mkcert -install mkcert localhost 127.0.0.1 ::1 # → produces localhost.pem and localhost-key.pemlocal-ssl-proxy) terminating TLS athttps://localhost:3001→http://localhost:3000. Verify with the team if they have a project-specific recipe — there may be a Caddyfile or proxy config already shared internally. - Polotno editor changes do not appear. You forgot to rebuild the bundle. See above.
yarn installfails on a clean checkout. This codebase mixes Vue 2 + React 18; some peer-dep warnings are expected and the install still succeeds. Hard failures usually mean Node version mismatch — check you are on Node 20.
What this doc does not cover¶
- How to log in / get a test user — ask the team for dev credentials.
- How to seed local data — there is no local seed script in this repo.
- How to run the backend locally — that is in the backend repo, not here.