Package version: @designcodeio/threeui@1.1.0 (also reproduces on 1.0.0, 0.3.0)
What's happening
SylvaLivingWorldScene renders its content in a sandboxed iframe: sandbox="allow-scripts", with no allow-same-origin. That makes the iframe a null-origin document.
The scene's own inner-green-3d.html declares:
@font-face{
font-family:'Lexend';
src:url('inner-green-assets/lexend-latin.woff2') format('woff2');
...
}
a root-relative fetch. From a null-origin iframe, that's a cross-origin request no matter what host actually serves it — and Chrome/WebKit require CORS approval specifically for cross-origin @font-face loads (unlike images or scripts, which can load no-cors). Console:
Access to font at 'https://<host>/inner-green-assets/lexend-latin.woff2' from origin 'null' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
The documented workaround doesn't apply to this component
The README says:
Components that render full HTML documents expect their runtime files at the same root-relative URLs used by the ThreeUI preview. Copy the needed files from node_modules/@designcodeio/threeui/lib-dist/assets/ into your app's public directory, or override the component's sourceUrl or assetBaseUrl prop where available.
SylvaLivingWorldSceneProps is exactly:
type SylvaLivingWorldSceneProps = {
variant?: "living-green";
className?: string;
style?: CSSProperties;
};
No sourceUrl, no assetBaseUrl. So the "override the prop" half of the documented fix isn't available for this component — only the "copy the file into your public dir" half is, and even that's insufficient on its own (see below).
Copying the file isn't sufficient either
I copied lexend-latin.woff2 to the exact expected path in my app's public/ dir. The font still failed to load with the same CORS error, because the request's Origin header is null (from the sandbox) and my server (a stock Next.js dev/prod server) doesn't send Access-Control-Allow-Origin for static files by default. The actual fix required adding an explicit CORS header for that path in my app's server config:
// next.config.ts
async headers() {
return [{
source: "/inner-green-assets/:path*",
headers: [{ key: "Access-Control-Allow-Origin", value: "*" }],
}];
}
That's a non-obvious requirement that follows directly from the allow-scripts-only sandbox choice, and it isn't mentioned anywhere in the README's asset-path guidance.
Ask
Either (or both):
- Expose
sourceUrl/assetBaseUrl on SylvaLivingWorldScene (and any other "full HTML document" component that's missing it), matching what the README already documents as the intended override.
- Document the CORS-header requirement explicitly wherever the "copy the file into public/" guidance appears, since it's not enough by itself given the sandbox.
Note: fixing this did not resolve the branch/foliage geometry never appearing (filed separately as #38) — that reproduces identically with or without this font loading successfully. Filing this as its own issue since it's a real, independent gap.
Package version:
@designcodeio/threeui@1.1.0(also reproduces on1.0.0,0.3.0)What's happening
SylvaLivingWorldScenerenders its content in a sandboxed iframe:sandbox="allow-scripts", with noallow-same-origin. That makes the iframe a null-origin document.The scene's own
inner-green-3d.htmldeclares:a root-relative fetch. From a null-origin iframe, that's a cross-origin request no matter what host actually serves it — and Chrome/WebKit require CORS approval specifically for cross-origin
@font-faceloads (unlike images or scripts, which can loadno-cors). Console:The documented workaround doesn't apply to this component
The README says:
SylvaLivingWorldScenePropsis exactly:No
sourceUrl, noassetBaseUrl. So the "override the prop" half of the documented fix isn't available for this component — only the "copy the file into your public dir" half is, and even that's insufficient on its own (see below).Copying the file isn't sufficient either
I copied
lexend-latin.woff2to the exact expected path in my app'spublic/dir. The font still failed to load with the same CORS error, because the request'sOriginheader isnull(from the sandbox) and my server (a stock Next.js dev/prod server) doesn't sendAccess-Control-Allow-Originfor static files by default. The actual fix required adding an explicit CORS header for that path in my app's server config:That's a non-obvious requirement that follows directly from the
allow-scripts-only sandbox choice, and it isn't mentioned anywhere in the README's asset-path guidance.Ask
Either (or both):
sourceUrl/assetBaseUrlonSylvaLivingWorldScene(and any other "full HTML document" component that's missing it), matching what the README already documents as the intended override.Note: fixing this did not resolve the branch/foliage geometry never appearing (filed separately as #38) — that reproduces identically with or without this font loading successfully. Filing this as its own issue since it's a real, independent gap.