Skip to content

Commit 33f720f

Browse files
authored
fix: Fix asset resource on published sites (#5565)
## Description 1. What is this PR about (link the issue and add a short description) ## Steps for reproduction 1. click button 2. expect xyz ## Code Review - [ ] hi @kof, I need you to do - conceptual review (architecture, feature-correctness) - detailed review (read every line) - test it on preview ## Before requesting a review - [ ] made a self-review - [ ] added inline comments where things may be not obvious (the "why", not "what") ## Before merging - [ ] tested locally and on preview environment (preview dev login: 0000) - [ ] updated [test cases](https://github.com/webstudio-is/webstudio/blob/main/apps/builder/docs/test-cases.md) document - [ ] added tests - [ ] if any new env variables are added, added them to `.env` file
1 parent 864b114 commit 33f720f

File tree

86 files changed

+1583
-125
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

86 files changed

+1583
-125
lines changed

.github/copilot-instructions.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
- Never use the `function` keyword - always use arrow functions (`const name = () => {}`) or function expressions with arrow syntax
1414
- Functions must never have more than 3 parameters - use an object parameter instead
1515
- Never alias the same type or variable to different names (e.g., `type AliasName = OriginalName`) - always use the original name consistently throughout the codebase
16+
- Spreading `undefined` works fine in JavaScript/TypeScript - the spread operator skips it. Never return empty objects `{}` when you can just `return` (or omit return for `undefined`). Example: `return { ...obj, ...maybeUndefined }` works correctly.
1617

1718
## Running Checks
1819

.github/workflows/main.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ jobs:
135135
const results = [
136136
await assertSize('./fixtures/ssg/dist/client', 356),
137137
await assertSize('./fixtures/react-router-netlify/build/client', 376),
138-
await assertSize('./fixtures/webstudio-features/build/client', 1056),
138+
await assertSize('./fixtures/webstudio-features/build/client', 3312),
139139
]
140140
for (const result of results) {
141141
if (result.passed) {

apps/builder/app/builder/shared/assets/asset-utils.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -269,7 +269,7 @@ describe("uploadingFileDataToAsset", () => {
269269
id: "test-id",
270270
name: "video.mp4",
271271
format: "mp4",
272-
type: "image", // Videos are treated as images for now
272+
type: "file",
273273
});
274274
});
275275

apps/builder/app/builder/shared/assets/asset-utils.ts

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -118,21 +118,17 @@ export const uploadingFileDataToAsset = (
118118
const assetType = detectAssetType(fileName);
119119

120120
if (assetType === "video") {
121-
// Use image type for now
122-
const asset: ImageAsset = {
121+
// Videos should be file type, not image type
122+
const asset: Asset = {
123123
id: fileData.assetId,
124124
name: fileName,
125125
format,
126-
type: "image",
126+
type: "file",
127127
description: "",
128128
createdAt: "",
129129
projectId: "",
130130
size: 0,
131-
132-
meta: {
133-
width: Number.NaN,
134-
height: Number.NaN,
135-
},
131+
meta: {},
136132
};
137133

138134
return asset;

apps/builder/app/shared/$resources/assets.server.ts

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
import { json } from "@remix-run/server-runtime";
22
import { parseBuilderUrl } from "@webstudio-is/http-client";
33
import { loadAssetsByProject } from "@webstudio-is/asset-uploader/index.server";
4+
import { toRuntimeAsset } from "@webstudio-is/sdk";
45
import { isBuilder } from "../router-utils";
56
import { createContext } from "../context.server";
6-
import { getAssetUrl } from "~/builder/shared/assets/asset-utils";
77

88
/**
99
* System Resource that provides the list of assets for the current project.
@@ -31,15 +31,10 @@ export const loader = async ({ request }: { request: Request }) => {
3131
const requestUrl = new URL(request.url);
3232
const origin = `${requestUrl.protocol}//${requestUrl.host}`;
3333

34-
// Convert array to object with asset IDs as keys and add URL to each asset
34+
// Convert array to object with asset IDs as keys
35+
// Use /cgi/ endpoint URLs (relative paths)
3536
const assetsById = Object.fromEntries(
36-
assets.map((asset) => [
37-
asset.id,
38-
{
39-
...asset,
40-
url: getAssetUrl(asset, origin).href,
41-
},
42-
])
37+
assets.map((asset) => [asset.id, toRuntimeAsset(asset, origin)])
4338
);
4439

4540
return json(assetsById);

apps/builder/app/shared/db/canvas.server.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,10 +63,11 @@ export const loadProductionCanvasData = async (
6363
}
6464
}
6565

66-
// Filter unused font assets
66+
// Filter unused font assets but include all other asset types (images, videos, audio, documents)
6767
const assets = allAssets.filter(
6868
(asset) =>
6969
asset.type === "image" ||
70+
asset.type === "file" ||
7071
(asset.type === "font" && fontFamilySet.has(asset.meta.family))
7172
);
7273

fixtures/README.md

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
# Webstudio Fixtures
2+
3+
Fixtures are test projects that ensure the CLI and build process work correctly across different deployment targets.
4+
5+
### Updating Fixtures After Changes
6+
7+
```bash
8+
# From repository root - updates all fixtures
9+
pnpm fixtures
10+
```
11+
12+
This command will:
13+
14+
1. Link all fixtures to their respective projects
15+
2. Sync the latest data from the development environment
16+
3. Build all fixtures with the latest code
17+
18+
### Working with Individual Fixtures
19+
20+
```bash
21+
# Go to fixture folder
22+
cd fixtures/webstudio-features
23+
24+
# Link to project
25+
pnpm fixtures:link
26+
27+
# Sync latest data
28+
pnpm fixtures:sync
29+
30+
# Build fixture
31+
pnpm fixtures:build
32+
33+
# Start it
34+
pnpm run dev
35+
```
36+
37+
## Adding Assets to Fixtures
38+
39+
To add a new asset (image, video, audio, etc.) to a fixture:
40+
41+
1. **Publish to staging**
42+
43+
- Make your changes in the builder
44+
- Publish to the staging environment
45+
46+
2. **Get the build ID from CI**
47+
48+
- After publishing, check the CI logs
49+
- Find the build ID that was created
50+
51+
3. **Update the fixture's build ID**
52+
53+
- Edit `fixtures/[fixture-name]/package.json`
54+
- Update the `--buildId` parameter in the `fixtures:sync` script
55+
56+
```json
57+
"fixtures:sync": "pnpm cli sync --buildId NEW_BUILD_ID_HERE && pnpm prettier --write ./.webstudio/"
58+
```
59+
60+
4. **Sync with the correct environment**
61+
62+
```bash
63+
# Go to fixture folder
64+
cd fixtures/webstudio-features
65+
66+
# Sync from staging environment (replace with your branch)
67+
BUILDER_HOST=fix-assets.staging.webstudio.is pnpm run fixtures
68+
```
69+
70+
5. **Fix the origin URL**
71+
72+
- After syncing, edit `.webstudio/data.json`
73+
- Change the origin back to:
74+
75+
```json
76+
"origin": "https://main.development.webstudio.is"
77+
```
78+
79+
- This is necessary because sync changes it to the current branch
80+
81+
6. **Commit the changes**
82+
```bash
83+
git add fixtures/
84+
git commit -m "chore: update fixtures with new assets"
85+
git push
86+
```

fixtures/react-router-cloudflare/app/__generated__/$resources.assets.ts

Lines changed: 12 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

fixtures/react-router-cloudflare/app/routes/[another-page]._index.tsx

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ import {
4040
import * as constants from "../constants.mjs";
4141
import css from "../__generated__/index.css?url";
4242
import { sitemap } from "../__generated__/$resources.sitemap.xml";
43+
import { assets } from "../__generated__/$resources.assets";
4344

4445
const customFetch: typeof fetch = (input, init) => {
4546
if (typeof input !== "string") {
@@ -71,6 +72,12 @@ const customFetch: typeof fetch = (input, init) => {
7172
return Promise.resolve(response);
7273
}
7374

75+
if (isLocalResource(input, "assets")) {
76+
const response = new Response(JSON.stringify(assets));
77+
response.headers.set("content-type", "application/json; charset=utf-8");
78+
return Promise.resolve(response);
79+
}
80+
7481
return cachedFetch(projectId, input, init);
7582
};
7683

fixtures/react-router-cloudflare/app/routes/_index.tsx

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ import {
4040
import * as constants from "../constants.mjs";
4141
import css from "../__generated__/index.css?url";
4242
import { sitemap } from "../__generated__/$resources.sitemap.xml";
43+
import { assets } from "../__generated__/$resources.assets";
4344

4445
const customFetch: typeof fetch = (input, init) => {
4546
if (typeof input !== "string") {
@@ -71,6 +72,12 @@ const customFetch: typeof fetch = (input, init) => {
7172
return Promise.resolve(response);
7273
}
7374

75+
if (isLocalResource(input, "assets")) {
76+
const response = new Response(JSON.stringify(assets));
77+
response.headers.set("content-type", "application/json; charset=utf-8");
78+
return Promise.resolve(response);
79+
}
80+
7481
return cachedFetch(projectId, input, init);
7582
};
7683

0 commit comments

Comments
 (0)