Repository navigation
Frontend Configuration
English | 简体中文 | Configuration overview
One-click installation uses deploy/build-frontend-offline.mjs to stage dependencies, build, and publish to <root>/public. “Offline” means locally served runtime assets; initial preparation of missing dependencies/emoji may still require network access.
Inputs are OJ_SITE_NAME (LLMOJ), HYHOJ_PUBLIC_DIR (<root>/public), optional HYHOJ_QUOTE_FILE (quotation JSON), and PNPM_BINARY (pnpm, used with --build). --assets-only stages assets and exits; --build builds and publishes; no flag publishes an existing dist. Passing both flags does not perform a full build because assets-only exits early. The build sets NODE_OPTIONS=--max-old-space-size=2300.
The following substitutions are currently fixed in the script, not additional environment variables:
| Placeholder | Local value |
|---|---|
__public_path__ |
/frontend |
__default_title__ |
OJ_SITE_NAME / LLMOJ |
__api_endpoint__ |
"" → / |
__favicon__ |
"" |
__applogo__ |
null |
__gravatar__ |
https://gravatar.com |
__ghavatar__ |
https://github.com |
__cdnjs__ |
/cdnjs |
Changing the name usually requires both backend preference.siteName and OJ_SITE_NAME during rebuilding. preference.misc.appLogo affects the logo after public configuration loads; the favicon and initial bootstrap assets belong to frontend publication. HYHOJ_PUBLIC_DIR does not update Nginx root. Publication rewrites output assets and index.html, and generates sw.js to unregister the old service worker and clear caches; generated output is not a permanent source-edit location.
With complete source and dependencies, the following example can run in a maintenance/build tree. It writes static files: back up the output first and substitute actual paths/name. Use the installer-compatible Node/pnpm and ownership, then verify the home page, asset loading, login, uploads, and browser caches.
cd /opt/LLMOJ
sudo env PATH=/opt/LLMOJ/runtime/node/bin:/opt/LLMOJ/runtime/tooling/node_modules/.bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin OJ_SITE_NAME="AI Practice" /opt/LLMOJ/runtime/node/bin/node deploy/build-frontend-offline.mjs --buildThe footer dynamically displays “site name Powered by LLMOJ”, using backend preference.siteName. Both LLMOJ and the GitHub icon link to houyhlouis/LLMOJ. Custom preference.copyrightNotice appears on a separate line; blank text and the exact defaults LLMOJ / LibreOJ Open Source Project do not add a duplicate line. Configuration is not rewritten. Initial titles and loading-error messages default to LLMOJ. Custom homepage content, original copyright, licenses and upstream attribution remain intact.
The administrator user menu includes Site management (/site-management), showing the effective registration mode, server default and whether an override is active. Saving or restoring the server configuration takes effect immediately. Ordinary users and accounts granted only review or homepage-editing permissions cannot use this management feature. Refresh an already-open registration page to display the current mode; see Registration approval.
Without a URL argument, packages/frontend/scripts/generate-api.js reads local Swagger at http://127.0.0.1:2002/docs-json. Pass the full Swagger URL for a different backend. This development API endpoint serves a different purpose from the project repository link.
packages/bootstrap-config/settings.json belongs to a separate bootstrap deployment system and is not read by local one-click installation. Its display title is LLMOJ; its API and asset examples still reference the upstream publishing services: replace them before independent deployment or requests/assets will point to someone else's site. This legacy path received a structural documentation review, not a deployment acceptance test.
env is a JSON dictionary, not process environment. The builder expands ${name} references in order, allowing later values to refer to earlier keys. All 15 current example keys are listed below; custom string keys can be added for substitutions.
| Key | Example (not local default) | Purpose |
|---|---|---|
env.title |
LLMOJ |
Initial page title |
env.cdnRoot |
https://static.cdn.menci.xyz/libreoj-frontend |
Frontend asset base |
env.apiEndpoint |
https://api.loj.ac |
Default-region backend address |
env.apiEndpointCN |
https://api.loj.ac |
CN-region backend address |
env.bootstrapCdnRoot |
bootstrap.loj.ac.cn |
Production bootstrap domain |
env.bootstrapCdnRootStaging |
bootstrap-staging.loj.ac.cn |
Staging bootstrap domain |
env.assets |
https://static.cdn.menci.xyz/libreoj-assets |
Common favicon/logo asset prefix |
env.favicon |
${assets}/favicon.ico |
Favicon URL |
env.appLogo |
${assets}/logo-website.min.svg |
Site logo URL |
env.gravatar |
https://gravatar.com |
Default Gravatar service |
env.gravatarCN |
https://cravatar.cn |
CN Gravatar service |
env.ghAvatar |
https://github.com |
Default GitHub avatar service |
env.ghAvatarCN |
https://cdn.menci.xyz/gh-avatar |
CN GitHub avatar service |
env.cdnjs |
https://cdnjs.cloudflare.com/ajax/libs |
Default dependency CDN |
env.cdnjsCN |
https://cdnjs.baoshuo.ren/ajax/libs |
CN dependency CDN |
A substitution value can be a string shared by all regions or a region-to-string mapping. Empty key "" is the fallback; CN is the current China-region example, with other codes extensible. Every current placeholder and mapping follows:
| Key | Value |
|---|---|
substitution.__api_endpoint__ |
{"CN": "${apiEndpointCN}", "": "${apiEndpoint}"} |
substitution.__default_title__ |
"${title}" |
substitution.__public_path__ |
{"": "${cdnRoot}"} |
substitution.__favicon__ |
{"": "${favicon}"} |
substitution.__applogo__ |
{"": "${appLogo}"} |
substitution.__gravatar__ |
{"CN": "${gravatarCN}", "": "${gravatar}"} |
substitution.__ghavatar__ |
{"CN": "${ghAvatarCN}", "": "${ghAvatar}"} |
substitution.__cdnjs__ |
{"CN": "${cdnjsCN}", "": "${cdnjs}"} |
substitution.__bootstrap_cdn_root__ |
{"": "${bootstrapCdnRoot}"} |
substitution.__bootstrap_cdn_root_staging__ |
{"": "${bootstrapCdnRootStaging}"} |
Rebuild bootstrap-config and the relevant bootstrap application, then deploy HTML/service-worker/static assets. Generated config.json fields responseDataForRegion, body, contentType, cacheControl, serviceWorker, and buildInfo are build outputs, not additional manual settings. This build path reads Git commit metadata; a source archive is not equivalent to a full Git worktree.
The Cloudflare variant requires CLOUDFLARE_WORKER_NAME and CLOUDFLARE_ACCOUNT_ID to generate wrangler.toml. The OSS variant requires ALIYUN_ACCESS_KEY_ID, ALIYUN_ACCESS_KEY_SECRET, ALIYUN_OSS_BUCKET, and ALIYUN_OSS_ENDPOINT and publishes CN-region pages. Neither is part of one-click deployment. Keep credentials out of settings.json and the Wiki; see Environment.
Sources: deploy/build-frontend-offline.mjs, packages/bootstrap-config/settings.json, packages/bootstrap-config/src/build.ts, apps/bootstrap-cloudflare/config.mjs, apps/bootstrap-static/deploy-oss.ts.
Submission and Hack lists use a fixed 1100 × 720 pixel window, bounded by the available screen. The window loads the original same-origin detail route in an iframe with embed=1; this flag hides the site navigation and its reserved spacing only within the embedded page. Normal detail links and the window’s #ID link keep the complete page. Authentication, code visibility, contest feedback and all actions use the original protected routes. See Submissions and Hacks.
The mode is captured when the frame starts, so ordinary links keep the embedded layout during client-side navigation. Lists reached inside the frame use normal links rather than nesting more preview windows. No additional backend permission or configuration switch is required.
简体中文
- LLMOJ Wiki
- AI 运行环境变量与固定限制
- AI 配置、权限与执行流程
- 后端配置完整参考
- 团队、题解、作废、Hack 与自测升级
- 配置总览与生效规则
- 比赛赛制
- 分布式评测与网页分离
- Docker 源
- 环境变量、构建与维护工具
- 前端与 bootstrap 配置
- HTTPS 与反向代理
- Hack
- 安装与端口配置
- 评测端完整配置与 CPU 扩缩容
- 基础服务与安装后运维配置
- 发布源码、版本与 GitHub Wiki
- 新用户注册审核
- 独立评测机安装
- Self Eval(NOI / OI 比赛预测试)
- 题解
- 评测记录 Fake
- 评测记录预览
- 团队
- 两步验证
- 保留配置与数据的一键升级
English
- LLMOJ Wiki
- AI configuration, permissions and execution
- AI runtime environment and fixed limits
- Complete backend configuration reference
- Teams, solutions, moderation, Hack and self-evaluation upgrade
- Configuration overview and activation
- Contest rules
- Distributed judging and web/judge separation
- Docker sources
- Environment, builds, and maintenance tools
- Frontend and bootstrap configuration
- HTTPS and reverse proxies
- Hacks
- Installation and ports
- Complete judge configuration and CPU resizing
- Infrastructure and post-install operations
- Source, release and GitHub Wiki publishing
- Registration approval
- Independent judge installation
- Self Eval for NOI / OI contests
- Solutions
- Fake submission moderation
- Submission previews
- Teams
- Two-factor sign-in
- Upgrading while preserving configuration and data