Skip to content
PapyrusReaderPublic

About

The website for the Papyrus project.

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Repository files navigation

Papyrus website

Public landing page for Papyrus, a free, open-source book library and reader. The website introduces the library, reading and optional sync features, presents the intended product feature set and format support, and directs visitors to the web app and separate direct downloads for Windows, Linux, Android bundles, and web archives.

Getting Started

npm ci
npm run dev

This starts a local server at http://localhost:8090 with live SCSS recompilation. JavaScript source files run directly. refresh after editing them.

Build deployable assets with npm run build. output is written to build/.

Design and assets

Product copy presents the core product requirements in present tense, rather than acting as a released-feature checklist. Its source is the project docs' index.rst and requirements/functional.rst: library organization and search, imports and metadata, reading, annotations, exports, goals, storage and sync. Speculative advanced ideas such as AI features and audiobooks are not included.

The website uses the client's purple identity with light/dark surfaces. It follows prefers-color-scheme until a visitor chooses a theme, then saves that choice in papyrus-theme. Legacy gold/purple choices migrate to light/dark. The small theme script loads before the stylesheet to avoid showing the wrong theme initially. Without JavaScript, the system theme, navigation, screenshot and download links remain usable. Reduced-motion preferences disable smooth scrolling.

Brand SVGs in public/img/ are copied from the client's public/img/ assets. The library screenshot is the original client README image, with local WebP variants at 640, 1280, 1920 and 2560 pixels. The full-resolution PNG is available through the enlargement link and is the social preview image. It always shows the real dark-mode app, independent of the website theme. Favicons use the canonical emblem from the client's app/assets/images/logo-icon-light.svg. These are checked-in assets. website builds do not need the client repository or image-generation tools.

Run npm test for the focused theme preference checks and npm run build for the static build. Review both themes at 320, 390, 720, 900, 1440 and 1920 pixels, including keyboard navigation, 200% zoom, reduced motion and JavaScript disabled.

Search indexing

The homepage includes a descriptive search title, a canonical URL, and JSON-LD for the Papyrus website and free application. Application platforms describe the available Windows/Linux downloads and browser app. Ratings and reviews are omitted until genuine reviews can be displayed. the markup does not yet meet Google's rating/review requirement for software-app rich results.

robots.txt and sitemap.xml are copied to the build root. The sitemap contains the canonical homepage and status page. Section anchors and the separate app/docs sites are not additional landing-page URLs. Add future public pages when they exist.

After deployment, submit https://papyrus-reader.com/sitemap.xml in Search Console and inspect the homepage using Test live URL and Request indexing. Google decides when to crawl and how to display the page in search results.

Releases and production deployment

The public website is served at https://papyrus-reader.com. www redirects there. It runs in its own papyrus-website Compose project on the Hetzner VM, separate from the app services. The shared papyrus-edge proxy owns ports 80/443 and routes website traffic to papyrus-website:8080 over the external Docker network. The Flutter app remains at https://app.papyrus-reader.com. Website versions in package.json are independent of client/server versions.

An administrator installs deploy/compose.yml at /srv/apps/papyrus-website/compose.yml and creates site/ there, owned by the dedicated upload account. After installing the first static build into site/releases/<commit> and linking site/current to that relative path, run docker compose -f compose.yml up -d --wait from this directory. The shared proxy/network must be provisioned first from the workspace's deploy/edge runbook. Website containers publish no host ports. They do not join the app's private network or mount its files.

Ordinary feature/fix PRs target the default development branch without a version bump. CI builds and tests integration changes without deploying them.

When ready to release, run npm version patch --no-git-tag-version to update package.json and package-lock.json in a preparation PR to development. Then open development → master and use Create a merge commit. Bring master back into development after the release. Keep both long-lived branches and do not squash release promotions. After merging into master, Website release builds only when that version increases. It verifies and deploys the archive, checks the public build revision, then publishes a GitHub release with its SHA-256 checksum. Run the workflow manually from master for the initial release or to retry the same version. A tag already belonging to a different commit requires a new website version.

The repository's production GitHub environment needs:

Setting Kind Value
WEBSITE_SSH_HOST Variable Hetzner server address
WEBSITE_SSH_USER Variable Dedicated papyrus-website user
WEBSITE_SSH_KNOWN_HOSTS Variable SSH host key verified through the existing administrator connection
WEBSITE_SSH_PRIVATE_KEY Secret Dedicated website upload key

Allow only master to deploy through that environment. The deployment account owns /srv/apps/papyrus-website/site and has no sudo or Docker access. The website's own container mounts that directory read-only. Each deployment validates the archive checksum, revision and required assets before atomically switching the relative current symlink to releases/<commit>. Previous releases remain available for rollback. Switch current back to an earlier relative release path without restarting any container. The app Compose project is not involved in website deployments. App releases do not restart the website or shared proxy.

Run the focused automation checks with python3 -m unittest discover -s scripts/tests -v. Normal website CI also builds the static assets. It never deploys pull requests.

Downloads and service status

Each platform expands from a compact download row to show its direct asset links. Native details and summary elements support keyboard navigation and work without JavaScript. Opening another platform closes the previous one in browsers that support named details groups. The checked-in links remain usable without JavaScript. With JavaScript, the page reads the latest published client release from GitHub and replaces links with that release's available assets. A failed or rate-limited lookup keeps the known release links and labels the lookup as unavailable. The APK link appears when the published release includes an APK. Tester installations use the separate Google Play opt-in link. Keep platform rows to names, architecture and download links. Put installation requirements and signing details in the GitHub release installation instructions. The website links to checksums, the manifest and release notes. These links use full-width rows on mobile.

/status/ reads a cached /status.json snapshot. A systemd timer probes API health and sync readiness once per minute, independently of site visitors. There is no refresh button and browsers never probe the services. Snapshots older than three minutes show Status unavailable. These are service health checks, without historical uptime or end-to-end account checks.

Install deploy/collect-status.py at /srv/apps/papyrus-website/collect-status.py and the two deploy/papyrus-status.* units in /etc/systemd/system/. Run systemctl daemon-reload, systemctl start papyrus-status.service and systemctl enable --now papyrus-status.timer. The restricted monitor owns only /var/lib/papyrus-status, which the website mounts read-only. Install deploy/Caddyfile beside the website Compose file and apply that project with docker compose up -d --wait. This one-time configuration update replaces only the website container. Subsequent website releases still switch static files without restarting services. /status.json is publicly cached for 30 seconds.

Describe features and requirements in plain, connected prose. Avoid slogans, filler, and strings of sentence fragments. Omit introductory copy when a heading and the content already explain the section. Use no semicolons in website prose.

About

The website for the Papyrus project.

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Contributors

Languages