These docs are new.
Expect rough edges. If something is missing or hard to follow, tell us on Discord or by mail at hallo@knecht.works.
Resources

Troubleshooting

Fix the differences a project can show on Knecht compared to your local DDEV setup.

Most projects boot on Knecht exactly as they do with DDEV locally. If yours doesn't, check the cases below, the exceptions we have met so far. Almost all of them share one cause: Knecht routes previews by hostname on one port, while the DDEV router convention puts a dev server on the same host and another port. A Vite dev server on Knecht therefore has its own origin, handed to the project as KNECHT_DEV_SERVER_URL. Any config that builds a "same host, other port" address needs to read that variable instead.

All fixes on this page are on the project side and leave local development unchanged. KNECHT_DEV_SERVER_URL is simply unset on your machine, so every fallback keeps working as before. After changing a Vite config, restart the session's dev server so the marker files are rewritten.

Laravel

Vite Origin from DDEV_PRIMARY_URL

Symptom. The preview loads, but /@vite/client, app.css, and app.js fail. The tags point at the preview host on port 5173.

Cause. vite.config.js builds server.origin from DDEV_PRIMARY_URL plus :5173. The Laravel Vite plugin writes that origin into public/hot, and Blade emits it verbatim. No value of DDEV_PRIMARY_URL makes "same host, other port" reachable on Knecht.

Fix. Prefer the Knecht variable and keep the DDEV branch as fallback:

server: {
  origin: process.env.KNECHT_DEV_SERVER_URL
    ?? (process.env.DDEV_PRIMARY_URL
      ? `${process.env.DDEV_PRIMARY_URL.replace(/:\d+$/, '')}:5173`
      : undefined),
},

Drupal

Dev/Dist Decision Cached Too Early

Symptom. A preview with a dev server configured still loads /dist/assets/..., without /@vite/client or HMR. Or the tags point at http://localhost:5173.

Cause. The drupal/vite module decides between dev server and dist build in hook_library_info_alter, so the decision is taken at drush cr and cached. With the default useDevServer: auto, it probes the dev server from PHP at that moment. The boot commands run drush cr before the dev server is up, so the probe fails and "dist" is cached. When the probe does hit, the default devServerUrl of http://localhost:5173 ends up in the HTML. The module also ignores Vite's base, so a base: '/dist/' config 404s on the dev server.

Fix. Switch explicitly in settings.php when Knecht hands the URL in, no probe involved:

if ($dev = getenv('KNECHT_DEV_SERVER_URL')) {
  $settings['vite'] = ['useDevServer' => TRUE, 'devServerUrl' => rtrim($dev, '/')];
}

In vite.config.js, set the base per mode: base: command === 'serve' ? '/' : '/dist/'. Run drush cr once after the change in a running session.

Kirby

Dev Server Origin Defaults to 0.0.0.0

Symptom. The preview loads, but /@vite/client and the app's CSS and JS are requested from http://0.0.0.0:5173, which the browser blocks.

Cause. kirby-vite switches to the dev server as soon as a .dev marker file exists and reads the browser-facing URL from it. vite-plugin-kirby writes that file when Vite starts, with server.origin or, when none is set, with <protocol>://<host>:<port>, which is http://0.0.0.0:5173 for a server bound to all interfaces.

Fix. One line in vite.config.js:

server: {
  origin: process.env.KNECHT_DEV_SERVER_URL,
},

Craft

devServerPublic Is a Literal DDEV URL

Symptom. The preview loads, but its module scripts point at https://<project>.ddev.site:3000/, which the browser cannot reach.

Cause. config/vite.php carries the browser-facing dev server URL as a literal, the DDEV router convention. Nothing in the Craft Vite plugin derives it from the request or from env. A second gate is useDevServer, usually CRAFT_ENVIRONMENT === 'dev', so that variable has to be set on Knecht too.

Fix. Read devServerPublic from env with a trailing slash and keep the DDEV URL as local fallback:

'devServerPublic' => App::env('KNECHT_DEV_SERVER_URL')
    ? rtrim(App::env('KNECHT_DEV_SERVER_URL'), '/') . '/'
    : 'https://myproject.ddev.site:3000/',

devServerInternal stays http://localhost:3000, Craft probes it from PHP inside the same container. Add CRAFT_ENVIRONMENT=dev to the project's environment variables in Knecht.

Custom Vite Setups

No Dev Branch at All

Symptom. The preview keeps loading /dist/assets/..., or shows a "no manifest entry" comment, whatever the dev server does.

Cause. A hand-rolled loader reads dist/.vite/manifest.json and nothing else. There is no plugin that knows about a dev server, so nothing ever emits /@vite/client. Often the Vite config pins no port either, and a base: '/dist/' puts the dev URLs under /dist/.

Fix. Branch in the loader: when KNECHT_DEV_SERVER_URL is set, emit the HMR client once plus a <link> and a <script type="module"> for the entry from that origin, otherwise the manifest path as before. In vite.config.js, pin the port and serve from the root in dev mode:

export default defineConfig(({ command }) => ({
  base: command === 'serve' ? '/' : '/dist/',
  server: { port: 5173, strictPort: true },
}))

Hit a project that behaves differently from your local setup and is not listed here? Tell us on Discord or at hallo@knecht.works, ideally with the symptom and the relevant config file.

Was this page helpful?