Blog /
Take a v0, Lovable, or Bolt export and put it on your domain
The Claude Artifacts case is the simple one: one HTML file, paste it in, done. v0, Lovable, and Bolt export differently, and each one has its own quirks. This post is the platform-by-platform import guide for the harder cases. None of them are blockers; all of them are predictable once you know what to expect.
The pattern that motivates each of these imports is the same: a tool built on a vibe-coding platform that works beautifully in the platform’s preview but never gets a permanent home on the site of the person who needs it. Someone builds a “find your perfect plant” quiz in Lovable for a content site, the Lovable app pulls from a Supabase table, the auth is wrong-shaped for the WordPress audience, and a couple of hours of trying to bridge the two worlds ends with “just link out to the Lovable URL.” Which becomes a link that gets clicked roughly never, because it’s not on the site’s domain and nobody remembers to link to it. The build was great; the home was nowhere.
v0 by Vercel
v0 outputs React components, by default targeting a Next.js project. You can’t paste a single React component into the DSGo importer; it expects HTML.
Two paths:
Build the v0 project to static HTML. Run npm run build && npm run export in the v0-generated Next.js project. The result is a out/ directory of static HTML files. Zip that directory, hand it to the DSGo importer’s bundle uploader (not the single-file uploader), and the importer treats each out/<route>.html as a route in your manifest.
Use v0’s “view source” download. v0’s editor has a “download as HTML” option for components that don’t depend on Next.js features. The output is a single HTML file with the component pre-rendered and inline styles. That goes through the single-HTML importer the same way a Claude Artifact does.
Quirks worth knowing:
- v0 components often pull in Tailwind via a CDN script tag. The importer detects this and flags it in the install dialog as “this app loads code from a third-party CDN.” You can either approve and accept the dependency, or vendor Tailwind into the bundle. For a one-shot tool, vendoring is overkill; for an app you’ll keep, vendor. CDN dependencies tend to outlive their CDNs.
- v0 sometimes references images via Vercel’s image-optimization endpoint (
https://...vercel.app/_next/image?url=...). Those won’t resolve once the bundle is on your site. Replace them with relative<img src>references to images you include in the bundle, or with data URIs. - v0’s icon imports (
lucide-react,@heroicons/react) compile to inline SVGs in the export. They survive. If your version uses a different icon library, make sure it’s compiled-in and not loaded at runtime.
Lovable
Lovable builds full app-shaped projects (auth, database, UI, sometimes AI integrations) on top of Supabase. The “deploy to DSGo” path is narrower: only the static-frontend half makes sense. Lovable’s “export project” gives you a Vite-built project; npm run build produces a dist/ directory.
Zip the dist/ directory, upload as a bundle, and the importer wires it up. The Supabase calls Lovable made in the original app become a question: do you want the DSGo App to talk to the same Supabase, or do you want to swap the data layer to the bridge?
If you keep the Supabase backend, declare it in runtime.external_origins:
"runtime": {
"external_origins": ["https://your-project.supabase.co"]
}
The CSP allowlists the origin. The site owner sees “this app talks to your-project.supabase.co” in the install dialog, which is the truth. Lovable apps frequently store user data in Supabase; if you’d rather keep that data inside WordPress, you’d swap each supabase.from(...) call for a dsgo.posts.list() or dsgo.storage.user.set() call. That’s a meaningful refactor, not a copy-paste; budget it accordingly.
The honest answer: if the Lovable app’s value is “it has a database,” the DSGo runtime can’t replicate Supabase’s full surface in v1. Use the import for the front-end and keep Supabase for the data layer until v1.x lands more bridge methods. The friend’s plant quiz could have lived on his domain that way; the database stays in Supabase, the front-end is a DSGo App, and the install dialog discloses both. Better than the standalone Lovable URL he ended up with.
Bolt
Bolt’s exports are the closest to “drop in and go.” Bolt projects build to static dist/ directories with no server-side dependencies; what you see in Bolt’s preview is what you get in the export.
Workflow:
# In the Bolt project after exporting:
npm install
npm run build
cd dist
zip -r ../bolt-app.zip .
Upload bolt-app.zip via the bundle importer. The manifest auto-generates with the routes Bolt produced as the routes array. View source on each route after import; you’ll see real HTML.
Quirks:
- Bolt apps that use Vite’s hot-reload module split tend to ship with absolute asset paths assuming the app is served at
/. If your DSGo App is at/apps/my-bolt-app/, the asset paths break. Two fixes:- Set
base: '/apps/my-bolt-app/'invite.config.jsbefore building. Vite rewrites the asset paths to match. - Or set the manifest’s
mount.modeto"root"(one app per site, mounts at/). The asset paths now work because the app actually is at/. Root mount is the right call for “the app IS the site”; it’s overkill for a single tool.
- Set
- Bolt apps frequently inline a chat-with-Bolt widget in the bottom-right. Strip it before exporting; it pings Bolt’s servers and confuses the install dialog. Bolt’s export options usually have a “production build” toggle that drops the widget; turn it on.
- Bolt’s preview environment is more permissive than your runtime. If a feature works in the Bolt preview but not in the import, the most common cause is a CSP violation: an inline event handler, a
style="..."witheval-shaped expressions, a third-party iframe. Open the browser console; CSP violations log there with the exact directive that blocked the call.
Generic patterns that work for all of them
A few rules of thumb that apply regardless of which platform produced the bundle:
Vendor your CDN dependencies. If the export pulls Tailwind, React, or anything else from a CDN script tag, replace those with bundled copies. The bundle’s a .zip; including 50kb of vendored code instead of a 200kb CDN script is fine. Self-contained bundles are easier to audit and don’t trigger the install-dialog warning about external CDNs. Self-containment is also resilience: a CDN can disappear, change its URL structure, or rate-limit you.
Strip platform-specific UI chrome. v0’s “edit in v0” button, Lovable’s chat overlay, Bolt’s “made with Bolt” badge: all of these reach back to their origin platform’s APIs and don’t survive the import. Remove them from the source before exporting, or remove them from the rendered HTML before zipping.
Set the base path correctly. If your build tool has a base-path setting (Vite’s base, Astro’s base, Next.js’s basePath), set it to match the URL the DSGo App will mount at. Most exports default to / and break when mounted at /apps/my-app/.
Test the bundle locally before deploying. Open the bundle’s index.html in a browser via file://. If it works there, it’ll work in the DSGo iframe. If it fails there with a CORS or asset-path error, fix that before importing. The DSGo runtime is not a magic environment.
The install dialog tells the truth. If the dialog flags external origins, third-party CDNs, or commerce endpoints, those activations come from manifest declarations the importer derived from the bundle. If something looks wrong, the manifest is wrong. The runtime is reading the same fields the dialog renders.
When the export isn’t worth importing
Sometimes the right call is to start over in a DSGo App scaffold instead of importing. Cases I’d skip the import:
- The export is a SaaS-shaped multi-page app with auth and a database. v0/Lovable/Bolt can target that; the import surface can’t yet reproduce all of it. Either pick a smaller subset to import, or rebuild the front-end inside
npx designsetgo apps initand use the bridge for data. - The export is heavy on platform-specific helpers (Vercel’s
next/image, Supabase’s Edge Functions). Those don’t resolve outside their original platform. Plan to swap them. - The export is in a framework that requires server-side rendering (Next.js with dynamic routes, SvelteKit’s adapter targets). The DSGo App runtime serves static bundles; SSR-only frameworks need to be exported to static first, which not every framework supports cleanly.
In all those cases, the right call is “use the export as a design reference and rebuild the relevant subset using the DSGo starter.” That’s harder than an import but smaller than the original engagement, because the design and the logic are already done.
The general lesson
Vibe-coding platforms are great at building the thing. They’re less great at deploying the thing somewhere it’ll have a permanent home. DSGo Apps adds the deployment story without changing what the platforms are good at. You build in v0 or Lovable or Bolt because those are good at building. You export, import, and run on your WordPress site because that’s where the app should live.
The bigger version of this argument is in the DSGo vs Bolt/Lovable/v0 post, which is a positioning piece rather than a tutorial. This one is just the import recipes.
Nealey