Rebuild the site on the stack the other converted sites share: Vite 8, React 19, TypeScript 7, react-router 8, Biome and sanitize.css, with the site data moved out of the bundle into static-contents/. - base the database and pico code on the other converted sites, keeping this site's layout, pages and item fields - read file timestamps as Unix seconds in the file and license views - serve all module data from modules/, redirecting the old download and /database/file URLs - keep form controls on white - track page views with GA4
3.8 KiB
OpenNeuro Repository
Static front-end for the archived INCF J-Node OpenNeuro Repository, 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/open.neuroinf.jp/). All of it lives in static-contents/, which sits
next to the repository rather than inside it:
open.neuroinf.jp/
├── open.neuroinf.jp/ this repository
└── static-contents/
└── modules/ one directory per source XOOPS module
├── credits/ pico: config.json, <content id>.json, images/
└── xoonips/ tree.json, items.json, file/<id>/
The RewriteBase in every modules/xoonips/file/<id>/.htaccess carries the
absolute path of that directory and has to move with the layout.
The dev and preview servers mount that directory at the site root. It is kept
out of dist/, and it is not tracked in git.
The site information pages (/credits/) come from a pico module named
credits. The XooNIps item types carry fields specific to this site (research
area, species, scale, method, referee, ...); they are marked
OpenNeuro extensions in src/database/, and the fields that render them are
the OpenNeuro* components in src/database/item-type/lib/field/. The top,
categories, overview and news pages and the page layout are in src/custom/.
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.
Styles
The base stylesheet is sanitize.css with its forms and typography sheets,
with its box-sizing: border-box kept. The site theme is
src/custom/assets/style.css. Where a sanitize.css default does not suit the
design, the rule for that place sets its own value rather than overriding the
element everywhere.
Deployment
Build locally and copy the result up; the server does not need a toolchain.
npm ci
npm run check
npm run build
../deploy.sh
deploy.sh, next to static-contents/, sends the data to
archive:/data/www/open.neuroinf.jp/static-contents/, then dist/ to
.../html/, and finally links every top-level entry of static-contents/ into
the document root over ssh (ln -sfn ../static-contents/* .). The data has to
go first: the document root's rsync --delete removes those links, and they
are only put back at the end.
Apache needs Options FollowSymLinks and AllowOverride All on both
directories. Use symlinks rather than Alias: an Alias maps the URL outside
the document root, so .htaccess no longer applies and the SPA fallback and
the redirects stop working.
Redirects
.htaccess redirects these addresses with a 301:
| From | To |
|---|---|
/modules/xoonips/download.php?file_id=N |
/modules/xoonips/file/N |
/database/file/... |
/modules/xoonips/file/... |
XOOPS-style addresses (/modules/xoonips/detail.php?item_id=N,
/modules/credits/..., /index.php) are redirected inside the app.
Google Analytics
GOOGLE_ANALYTICS_TRACKING_ID in src/config.ts carries the GA4 measurement
ID. Emptying it disables tracking. Only production builds send page views.