← All notes

A working local preview can still break after publishing

Old image references, omitted assets and live 404s from a portfolio refresh, with a small Python standard-library checker for direct page assets.

The new images were ready, but old problems remained

The 13 November update captured 43 project screenshots and replaced the homepage thumbnails, directory images and enlarged previews together. Local checks passed. A check of the published pages then found a broken AI settings image in the directory. Comparing the asset list exposed another missing historical archive image.

The missing paths were assets/ai-settings-desktop.png and assets/archive-center-desktop.png. Both existed locally and were already referenced by the HTML. After those images were uploaded, the live check found a 404 for cases/ai-office/ai-office.css. The page still opened, but its case-specific layout was missing.

HTTP · 本次实际遗漏的资源 / Missing resources in this release
assets/ai-settings-desktop.png
assets/archive-center-desktop.png
cases/ai-office/ai-office.css

The local folder and the published file set differ

This release uploaded an explicit list of files. That avoids including caches, evidence folders or private material, but it creates a gap: a file can exist locally without appearing in the publication list. The local browser can fetch it without knowing whether it will be committed.

The local preview server also had a fallback folder for older assets. That helped display unchanged pages while making the local environment even less like the published site. In this incident, the two images already existed in the main local folder, so the fallback was not their sole cause. A separate preview containing only the intended release files would make omissions visible earlier.

The thumbnail and enlarged view need the same update

A card's img.src and its button's data-preview hold separate URLs. Updating only the image can leave the old version in the enlarged view. The same project also appears on the homepage, in the gallery and on the GitHub profile. An asset list makes these references easier to inspect together.

The new images live under a 20261113 directory with new URLs. That reduces reuse of an older cached image at the same path and records the capture batch. New filenames do not solve every cache problem: the HTML can still be cached, so the published response needs checking too.

JavaScript · 浏览器核对示例 / Browser-check example
const button = page.locator('#project-fieldlens [data-preview]');
const previewURL = await button.getAttribute('data-preview');
const thumbnailURL = await button.locator('img').getAttribute('src');
if (previewURL !== thumbnailURL) {
  throw new Error('Thumbnail and full-size preview do not match');
}
await button.click();
await page.waitForFunction(() => {
  const image = document.querySelector('dialog[open] .lightbox-image');
  return image?.complete && image.naturalWidth > 0 && !image.hidden;
});

Automate the omissions that are easy to detect

The accompanying check-public-assets.py uses only the standard library. Given explicitly selected public pages, it extracts direct image, stylesheet, script and source URLs, deduplicates them and makes same-origin GET requests. It fails on 404s and on assets that return HTML, which can otherwise hide behind a site's fallback page.

By default it checks this site's project directory and AI case. The --base option can select your own local preview. It does not crawl page links, request other origins or send login credentials. Asset responses are sampled at 1 KB, HTML is limited to 1 MB, and the run accepts up to 10 pages and 200 assets with a 12-second request timeout. This scope catches missing uploads; it does not establish complete media files, working scripts or a fault-free site.

When compiling this note, five local HTTP behavior tests passed, covering missing files, HTML fallbacks, duplicate references, base URL resolution, cross-origin redirects and oversized pages. A separate run checked the two selected live pages and 57 direct assets without request failures. Fonts and background images inside CSS, and resources created by scripts, still need browser checks.

Shell · Python 3.10+
# 在仓库根目录执行 / Run from the repository root
python notebook/examples/check-public-assets.py projects.html cases/ai-office/

# 检查只包含本次发布产物的本地预览 / Check a release-only preview
python notebook/examples/check-public-assets.py --base http://127.0.0.1:8000/ index.html

# 运行离线行为测试 / Run local HTTP behavior tests
python notebook/examples/check-public-assets-test.py

Exit code 0 means the requested checks passed, 1 indicates a page or asset failure, and 2 indicates invalid arguments. External resources are recorded as skipped, not verified.

Captions need the same review

The review also found two content mismatches. The new FieldLens list had no records selected, while its old caption said two were selected. A counselor card previously showed the local application while linking to a separate public showcase. Successful image loading does not make those descriptions accurate.

The captions now describe what is actually visible: record count, current action scope, and whether the view is a public demo or a historical local interface. Synthetic tasks can illustrate interaction design, and an early-stop animation can explain a process, but neither establishes production use or a training result. Historical images can stay if their dates and scope remain clear.

After deployment, follow the reader's path

The final check starts on the published homepage: inspect a project card, enlarge the image, open its case and follow the demo link. The 13 November records covered 34 language-and-width combinations and 64 preview openings. After the missing AI case stylesheet was restored, that page was checked again in both languages at 390 and 1440 pixels. These counts describe the performed checks, not every device or business workflow.

The useful habit is to record committed, deployed and checked online as separate states. A commit confirms repository content; a deployment confirms the build process; the page readers receive still needs a check at its live URL. On a portfolio that grows over time, an old page's dependency can become a problem in a new release.

About this example

Compiled on 15 November 2026 from this site's 13 November screenshot refresh and its verification records: 20 runnable projects and learning demos, 43 screenshots, followed by two missing historical images and one case stylesheet. This is a static-site release review, not full business acceptance of every demo. The example checks direct same-origin assets in selected public pages; it does not execute JavaScript or inspect all CSS dependencies.

Sources & further reading

Drafting and translation assisted by AI. See the sources and example scope above.