Skip to content
PortBay

Qwik City routes, edited down to the line of .tsx

Qwik's scaffold ships a real Vite config, so PortBay stamps the dev server it launches for you and every element you wrote maps to its line of .tsx. One tier does not map, and this page says which. Pro, early access, opt-in.

The short answer

How do I visually edit a Qwik City route?

Qwik City keeps a route's markup and its head values in one src/routes/**/index.tsx file, so a visual editor has a single place to write. What it needs first is a way into the dev server. Qwik's scaffold ships a direct Vite dependency and a real vite.config, so PortBay launches that server and passes it a generated config adding a source-location plugin — nothing to install, and your project byte-identical. Elements you wrote then carry their file, line and column, and an edit is spliced into that span. One limit is real and shared with every JSX file: an element produced by a component you did not author carries no coordinate, because a capitalised tag in a .tsx can also be a TypeScript generic parameter list. Page settings write into the route's exported DocumentHead. Pro, early access, opt-in.

Verified against the product, 2026-09-05.

In the app

A Qwik City route, stamped

acme-shop · Board6 cards3 agents online
Pending2
infra
Rate-limit the API
P1
Dark mode polish
P2
Todo2
auth
Add OAuth login
P0Claude Code0/3oauth-login
Auto-dispatching
implement OAuth on app.test
db
Migrate to Postgres
P1
In Progress1
Fix flaky checkout test
P0
Done2
Set up Mailpit inbox
P2
Seed demo data
P2
1/5 · AssignA card lands in Todo and @claude is mentioned

PortBay runs your Qwik project at its own .test URL with trusted HTTPS and dispatches board cards into it. The visual editor edits that same running app in your real browser — one live route, not a multi-frame design canvas.

Walkthrough

Your first Qwik route edit

Four steps, none of them an install. Qwik gets here through the ordinary Vite lane, because its own scaffold already ships what that lane needs.

  1. Install PortBay and add your Qwik project
  2. Turn the visual editor on
  3. Start the project — the stamping rides your own Vite config
  4. Open Edit in browser and change something

Install PortBay and add your Qwik project

Homebrew installs the app and the bundled portbay CLI. Add the project folder and PortBay recognises Qwik from @builder.io/qwik in your package.json, runs your dev server, and serves it at its own .test hostname over trusted HTTPS.

brew tap portbay-app/portbay && brew install --cask portbay

Turn the visual editor on

It ships to Pro under early access and is off by default. Sign in to Pro, then flip the Early Access toggle. The open-source build does not include the editor at all — it is not compiled in.

Settings › Account › Early Access

Start the project — the stamping rides your own Vite config

A Qwik scaffold ships a direct Vite dependency and a real root vite.config.ts, which is exactly the seam PortBay needs. It generates a config that imports and spreads yours, adds one plugin, and points the dev server at it. The generated file lives in PortBay's data directory, never in your repo, and the plugin applies only while serving, so qwik build never loads it.

portbay start myapp

Open Edit in browser and change something

The project's Visual editing section has one button. It opens your normal browser at your normal .test URL with the edit bar docked at the top, booting in Preview mode where resumability and your event handlers still work normally. Switch to Edit, double-click text to type into the live page, then Save. Tailwind design tokens are editable too, and renaming one rewrites every class referencing it across the project in the same save.

https://myapp.test/about
Without PortBay

What maps in a Qwik route, and what doesn't

Qwik routes are .tsx, so they sit on the script-first side of the stamper. That gives you every element you wrote and stops at markup a dependency produced. Worth knowing before you judge a result.

In practice: everything in your own src/ maps to its own line. A design-system component you installed renders markup that does not, and PortBay says so rather than writing into the nearest plausible file.

Questions

Asked before downloading

No. The default Qwik scaffold ships a direct Vite devDependency and a real root vite.config.ts, which is the seam PortBay needs. It launches your dev server with a generated config that imports and spreads your own and adds a source-location plugin carried inside the app itself. Nothing is written into your repo and there is no package to add — your package.json, lockfile and vite.config stay byte-identical.

Then it drops to the text-matching lane. A project exposing neither a vite dependency nor a vite.config gives PortBay no dev server it can reach, so text, class and attribute edits resolve by searching your source rather than by following a coordinate, and structural edits are refused rather than guessed. The default scaffold ships both, so this is the unusual case rather than the normal one.

Component usages. Route files are .tsx, a script-first format, so the host elements you wrote carry coordinates but a <Hero /> tag does not. Your own components are still fine — the elements inside them are stamped at their own lines in their own files. What genuinely has no coordinate is markup produced by a package you did not author. The reason is grammatical: a capitalised tag in a .tsx can be a TypeScript generic parameter list, and inserting an attribute into the wrong one is a syntax error in your module.

Through the route's exported DocumentHead object literal. Qwik City reads that export for exactly that route and nothing else's, so a value written there cannot leak onto another page. An absent field is inserted rather than refused — as a new key on the existing object, or as a brand-new export const head appended to the route when it has none at all.

The edit bar boots in Preview mode, where the page and your event handlers behave exactly as they normally do, and switching to Edit changes what your clicks mean rather than what the app is. More importantly, the edit is written to your source file, so what you get afterwards is the same app rebuilt from changed source — not a runtime patch layered over a running page.

No. The plugin declares apply: 'serve', so Vite loads it for the dev server and never for a build. There is nothing to leave behind in your source either, because the attribute is added while the file is served rather than written into it — the difference from editors that insert their own id attributes into your components and expect you to remove them before shipping.

No. It is a Pro feature, still in early access behind an opt-in toggle in Settings, and it is not compiled into the open-source build. It also refuses to run while the project is shared over a public tunnel, and the edit bar works only on local .test hosts. Running Qwik on a real .test domain with trusted HTTPS is in the free, open-source app.

Yes. JSX and TSX are among the four formats where that structural edit is supported, so an element in a route file can be moved into a new component file, its import added, and the span it vacated replaced by the tag. The one deliberate refusal is a span carrying a template expression, which is named rather than attempted — the values it closes over are locals of the route and would not exist in the new file.

PortBay mascot — a friendly blue tugboat

Give your projects and your agents a real local home.

Download for macOS

Free & open source · macOS 11+ on Apple Silicon · Pro from $10/mo