sanitize.css forms.css makes inputs, selects and buttons transparent. Give them a white background through the classes and blocks they are used in.
BMI Platform
Static front-end for the archived BMI Platform (Brain Machine Interface Platform), built with Vite, React and TypeScript.
The app serves two halves of the site:
| Path | Content |
|---|---|
/ |
the portal: papers, original contents, press releases, research sites, materials, column |
/researchers/ |
the XooNIps database and its site information |
Each half keeps its own theme. The two stylesheets style the same selectors
(body, #header, #main, ...), so src/main.tsx loads only the half the
URL belongs to, as its own chunk. Links between the halves are plain anchors
and load the other half from scratch.
Requirements
- Node.js 20.19+ / 22.12+ (Vite 8)
- npm
Setup
npm install
Source layout
src/
├── main.tsx picks the half of the site to load
├── config.ts site title, GA4 ID, RESEARCHERS_URL
├── common/ shared by both halves (XoopsCode, LangFlag, page tracking, ...)
├── front/ the portal: layout, pages, theme
└── researchers/ the XooNIps database: layout, database/, credits/, theme
Site data
The data lives in static-contents/, which sits next to the repository rather
than inside it:
bmi.neuroinf.jp/
├── bmi.neuroinf.jp/ this repository
└── static-contents/
├── modules/bmi/ the portal's data (credits, press, materials, research sites)
├── images/ portal images referenced by that data
├── contents/ documents linked from the portal (BCI.pdf)
└── researchers/
├── modules/xoonips/ tree.json, items.json, rankings, file/<id>/
├── modules/credits/ credits.json
├── images/ images referenced by the XooNIps content
└── rss.xml
The RewriteBase in every researchers/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
deliberately kept out of dist/, and it 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.
Styles
The base stylesheet is sanitize.css with its forms and typography sheets.
Its box-sizing: border-box is kept, so sizes in the themes are border-box
totals. Where one of its defaults does not suit a theme, the theme 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/bmi.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.
/researchers/ is a real directory on disk as well as an SPA route, so
public/.htaccess sends every request that is not a real file to
index.html, directories included.
Redirects
.htaccess redirects these addresses with a 301:
| From | To |
|---|---|
/researchers/modules/xoonips/download.php?file_id=N |
/researchers/modules/xoonips/file/N |
/researchers/database/file/... |
/researchers/modules/xoonips/file/... |
XOOPS-style addresses (/researchers/modules/xoonips/detail.php?item_id=N,
/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.