Theme Dev Preview
The SDK theme dev preview lets you test a theme you're building locally against a real profile page — with live user data, real link icons, and real installed apps — without uploading a bundle or changing the profile's active theme for anyone else.
How to use it
- Create a Developer Project at
My Apps → Developer Modeand point it at your local dev server (e.g.https://shuuka-theme.local). - Note the numeric project ID shown in the dev mode page.
- Open any profile URL and append
?dev_theme={id}:https://shuuka.com/username?dev_theme=2 - The page renders with your local theme. No other visitor sees the change.
Only the authenticated profile owner can use ?dev_theme. It is silently ignored for all
other visitors.
What the platform does
When ?dev_theme={id} is present:
- The API fetches your local
theme.config.jsonand merges it with the user's active theme settings — keeping profile data, links, and app layout intact. config.iframein the merged result is replaced entirely with your theme's owniframesection. This prevents the user's production card settings (background, shadow, radius, etc.) from leaking into your theme's card design through inline CSS.- The theme entry URL is set to
https://api.shuuka.com/en/v1/dev-theme/{id}/entry. - The profile page loads an
<iframe>pointed at that URL. - The API proxy fetches
index.htmlfrom your dev server, rewrites./-relative asset paths to serve through the proxy (so/sdk/js/…imports resolve correctly), and returns the modified HTML.
Path resolution inside your iframe
Your theme iframe runs from api.shuuka.com (the proxy URL), not from your dev server's
origin. URL resolution changes accordingly:
| Path type | Example | Resolves to |
|---|---|---|
./-relative | ./dist/index.js | Proxied to your dev server ✅ |
| Root-relative SDK | /sdk/js/index.js | api.shuuka.com/sdk/js/… ✅ |
| Root-relative icons | /social_icons/shuuka-Instagram.png | api.shuuka.com/social_icons/… ✅ |
| Vite dev src | /src/index.js | api.shuuka.com/src/index.js ❌ 404 |
Important: When your dev server is running Vite, the theme's
src/index.jsmodule is served by Vite at/src/index.js. When proxied through the API, this path 404s because there is no/src/directory on the API server.Production bundle (
./dist/index-xxx.js) is not affected — it uses a./relative path, which the proxy rewrites correctly.
What this means for your SCSS
Because src/index.js (the CSS vars bridge) does not load in Vite dev proxy mode, all
your CSS custom properties need var(…, fallback) defaults in your SCSS that match your
theme.config.json exactly:
.shk-theme__app-card {
background: var(--app-card-bg, rgba(255, 248, 230, 0.045));
border-radius: var(--app-card-radius, 18px);
box-shadow: var(--app-card-shadow, 0 8px 32px rgba(0, 0, 0, 0.60));
border-color: var(--app-card-border-color, rgba(201, 168, 76, 0.12));
}
.shk-theme__link {
width: var(--links-icon-size, 52px);
height: var(--links-icon-size, 52px);
}
Initial appearance will look correct. Live dashboard preview edits will only propagate after a hard reload (when using Vite dev mode). With the production built dist, both initial appearance and live preview work fully.
Requirements for your theme files
theme.config.json
Must include an iframe section, a links section, and meta.color_scheme:
{
"meta": {
"name": "My Theme",
"version": "1.0.0",
"color_scheme": "dark"
},
"config": {
"iframe": {
"background": "rgba(0, 0, 0, 0.5)",
"border_radius": 16,
"shadow": "md",
"padding": 0,
"border_style": "solid",
"border_width": 1,
"border_color": "rgba(255, 255, 255, 0.1)"
},
"links": {
"visible": true,
"alignment": "center",
"wrap": true,
"item_size": 48,
"spacing": 8
}
}
}
Without the iframe section, the platform replaces config.iframe with [] — no inline
card CSS vars are set, only your SCSS fallbacks apply.
Without color_scheme, embedded app iframes receive no dark/light signal and default to
light mode.
src/index.js
Must implement applyIframeCssVars(cfg) and applyLinksCssVars(cfg) and call them inside
the shuuka:contextSnapshot / shuuka:ctx message handler. These functions write CSS
custom properties to :root, keeping card and link styles in sync with dashboard preview
changes.
See the platform developer reference (docs/SDK_THEME_DEV_PREVIEW.md) for the canonical
implementation.
Social icons in dev preview
Social network link icons are rendered as:
<img src="/social_icons/shuuka-Instagram.png" alt="" loading="lazy">
Inside your proxied iframe (origin: api.shuuka.com), the root-relative path resolves to
api.shuuka.com/social_icons/shuuka-Instagram.png — served from the API server's
public/social_icons/ directory.
If icons appear missing:
- Open browser DevTools → Network → filter
social_icons - Confirm requests return
200fromapi.shuuka.com - If
404: a file is missing from the API server'spublic/social_icons/folder
Keeping local dev and the platform-apps bundle in sync
Once your theme is ready to be published, the files in
resources/platform-apps/Themes/<name>/ must be identical to your local dev source.
# Verify they are in sync:
diff resources/platform-apps/Themes/<name>/src/index.js \
/path/to/your-theme-local/src/index.js
# After any change to src/index.js, rebuild the dist:
cd resources/platform-apps/Themes/<name>
npm run build
The built dist/ is what the proxy serves in production via the ./ relative path.