Set the measurement ID that replaces the Universal Analytics property shut down in 2023, which leaves tracking disabled until now. Update the README section, which still described the ID as empty.
Visiome Platform
Static front-end for the archived Visiome Platform site, built with Vite, React and TypeScript.
Requirements
- Node.js 20.19+ / 22.12+ (Vite 8)
- npm
Setup
npm install
Site data
The pages are rendered from JSON dumped out of the original XooNIps/XOOPS
installation by xoops-static-exporter
(sites/visiome.neuroinf.jp/).
All of it lives in static-contents/, which sits next to the repository rather
than inside it:
visiome.neuroinf.jp/
├── visiome.neuroinf.jp/ this repository
└── static-contents/
├── modules/ one directory per source XOOPS module
│ ├── credits/ credits.json
│ ├── manual_ja/ config.json, <content id>.json, images/
│ ├── primface/ config.json, <content id>.json, images/
│ └── xoonips/ tree.json, items.json, file/, ...
└── rss.xml
Each pico module keeps its own config.json — the index of its categories and
pages — next to the page bodies it describes.
The dev and preview servers mount that directory at the site root. It is
deliberately kept out of dist/: it runs to gigabytes, and the web server maps
it in directly. It is generated content and is not tracked in git.
Scripts
| Command | Description |
|---|---|
npm run dev |
Start the dev server on http://localhost:5173 |
npm run build |
Type-check and build into dist/ |
npm run preview |
Serve the production build on http://localhost:4173 |
npm run lint |
Lint with Biome |
npm run format |
Format with Biome |
npm run check |
Lint, format and organize imports, applying the safe fixes |
@types/node is pinned to the major that matches the Node runtime in use (24);
.ncurc.js keeps npm-check-updates from bumping it past that.
There is currently no test suite.
Deployment
Build locally and copy the result up; the server does not need a toolchain.
1. Build and check
npm ci
npm run check # biome, writes fixes
npm run build # runs tsc -b, then vite build
npm run preview # localhost:4173 , serves dist/ + static-contents/
dist/ is a few MB. static-contents/ is never part of it — the dev and
preview servers mount it, and in production the web server maps it in.
2. Send up the site data
About 10 GB, almost all of it under modules/xoonips/file/. The server mirrors
the local layout: static-contents/ sits next to the document root. Run this
from the directory that holds both the repository and static-contents/:
/data/www/visiome.neuroinf.jp/
├── html/ document root
└── static-contents/
rsync -a --delete static-contents/ \
user@server:/data/www/visiome.neuroinf.jp/static-contents/
3. Push the build
rsync -a --delete dist/ user@server:/data/www/visiome.neuroinf.jp/html/
--delete clears out the previous build, and with it the data symlinks from
step 4 — that is deliberate, they are recreated right after. Anything left over
from an older deployment goes too.
4. Link the site data into the document root
cd /data/www/visiome.neuroinf.jp/html
ln -s ../static-contents/* .
That links every top-level entry of static-contents/ — currently modules/
and rss.xml:
/data/www/visiome.neuroinf.jp/html/
├── index.html from dist/
├── assets/ from dist/
├── .htaccess from dist/
├── modules -> ../static-contents/modules
└── rss.xml -> ../static-contents/rss.xml
The glob keeps the two in step, which matters because rss.xml sits beside
modules/ rather than inside it: linking modules alone leaves /rss.xml
returning 404, a break that npm run preview cannot reproduce because it mounts
the whole directory. It also picks up anything added to static-contents/
later. Note that it skips dotfiles, of which there are none today.
The links are relative, so the whole tree can be moved without rewriting them.
Run steps 3 and 4 back to back. In between, /modules/... and /rss.xml are
404 because step 3 removed the links; that is why plain ln -s works here
without -f, and why a stale or wrong link repairs itself on the next deploy.
Apache needs Options FollowSymLinks, AllowOverride All and
Require all granted on the document root, and Options FollowSymLinks with
Require all granted on static-contents/.
Use symlinks rather than Alias. An Alias /modules ... maps the URL outside
the document root, so .htaccess no longer applies to it and every legacy
/modules/xoonips/*.php URL stops reaching the SPA redirect handler. With
symlinks the normal precedence still holds: real files are served directly and
everything else falls through to index.html.
5. Check the deployed site
curl -I https://visiome.neuroinf.jp/rss.xml # 200
curl -I https://visiome.neuroinf.jp/database/file/3.png # 301
curl -I https://visiome.neuroinf.jp/modules/xoonips/tree.json # 200
Then load /, an item page, /primface and /manual_ja/manual.html in a
browser and confirm the images resolve.
Upgrading from v1.0.0
v1.0.0 served the data from database/, credits/, pico/, manual_ja/ and
primface/ at the site root; it all moved under modules/. Nothing extra is
needed: --delete in step 2 clears the old data layout, and --delete in
step 3 removes the v1.0.0 symlinks from the document root along with the old
build.
Run steps 2 to 4 back to back: in between, the live v1.0.0 build points at paths that no longer exist.
The v1.0.0 download links stay alive. .htaccess sends /database/file/... to
/modules/xoonips/file/... with a 301. The links inside rss.xml are legacy
XOOPS URLs (/modules/xoonips/detail.php?item_id=), unaffected by the move and
resolved by the SPA as before.
Google Analytics
GOOGLE_ANALYTICS_TRACKING_ID in src/config.ts carries the GA4 measurement
ID that replaced the Universal Analytics property shut down in 2023. Emptying
it disables tracking.