This directory contains the documentation files and static site generator for nextstrain.
For general nextstrain.org
documentation including the nextstrain server (including the /charon/...
API endpoints) and auspice customizations, see nextstrain.org/README.md.
The static-site is built using Next.JS. An understanding of Next.JS concepts will be generally helpful for understanding the different moving parts however this README will attempt to link to the salient documentation as needed.
There are no specific dependencies or software defined within ./static-site
, so all that's needed is to follow the installation instructions in the parent directory's README.
TL;DR: In the parent directory, run
node server.js
with your usual environment variables, or runnpm run dev
which will also watch for any changes to the server code. Both will serve the pages defined here using hot-reloading so that any changes are immediately reflected on localhost.
See our routing docs for a high level overview of the routing used in nextstrain.org
We use Next.JS' Pages Router to define routes based on filenames within ./static-site/pages
.
The Next.JS dynamic routing docs explain mapping between filenames and URL paths.
Currently these are the only Next.JS pages we serve. If the path doesn't exist in ./static-site/pages
(and it's not handled elsewhere by the nextstrain.org server) then the default 404 page will be displayed.
As alluded to in our routing docs the presence of Next.JS routing + our own server routing can cause conflicts if not used appropriately. We'll use an example here to demonstrate how such a conflict could occur:
We currently route requests for /zika
to the auspice entrypoint.
If a Next.JS page ./static-site/pages/zika.jsx
existed then requests to /zika
would still go to Auspice, because that route takes priority in our nextstrain.org server route hierarchy.
However if we included a client-side <Link href='/zika'>
component then via client-side routing you would be able to load the Next.JS Zika page. (Refreshing the page would go back to Auspice, as the browser would make a new request to /zika
.)
Please don't do this!
In production mode all pages are statically generated at build time.
Whilst pages may make API requests to the server for information, there is no server-rendering involved.
This mode can be used during development by setting the env variable USE_PREBUILT_STATIC_SITE=1
; don't forget to build the static-site before running the server (e.g. npx next build static-site
).
In development mode the pages are dynamically served by the server to allow hot-reloading etc (this is the default situation if you don't specify NODE_ENV=production
or USE_PREBUILT_STATIC_SITE=1
)
Prior to using Next.JS we used Gatsby which enforced a specific folder structure which is still visible within ./static-site/src
.
This file structure was kept during the migration to Next.JS but no longer has any significance.
We maintain it here for simplicity but at some point we may do a mass file reorgansiation.
The vast majority of Next.JS pages within ./static-site/pages
are files of only a few lines which import & re-export the appropriate component from within ./static-site/src
.
We use a static-site/public
directory for assets which are exposed at the root (nextstrain.org) URL.
At the moment these largely consist of images used in blog posts.
When starting the server you may see a warning message:
⚠ The static directory has been deprecated in favor of the public directory.
However assets within this directory (./static-site/static
) are not exposed.
We may wish to rename this directory to avoid any doubt.
- Navigate to the Auspice view and take a square screenshot of a panel that is representative of the data.
- If using a tree, make sure branch labels are turned off.
- Downsize the image to 250px by 250px.
- Save the file in
./static/pathogen_images
- Add a new entry to ./content/featured-analyses.yaml.
To add a new team member to the nextstrain.org/team page, make a PR in this repo with the following changes:
- Add an image for the team member to the ./static/team directory.
- Add an entry for the team member to the ./src/components/People/teamMembers.js file in the appropriate list. Note that the lists are currently ordered by alphabetical order by the last names.
After the above PR is merged, the new team member can then be added to the docs.nextstrain.org footer.
- Make a PR in the nextstrain/sphinx-theme to update the custom footer with the new team member.
- Merge the PR and follow instructions to release a new version of the theme on PyPI.
- Once the new version is available on PyPI, trigger RTD rebuilds for the latest/stable doc versions to update the footer.
To author a new blog post, create a new file under /static-site/content/blog/
following the existing file naming convention (YYYY-MM-DD-the-title-here.md
, e.g., 2024-11-14-blog-posts-are-awesome.md
). The file should start with a block of YAML front matter, such as:
---
author: "James Hadfield"
date: "2018-05-14"
title: "New nextstrain.org website"
sidebarTitle: "New Nextstrain Website"
---
followed by the content of the blog post, marked up using Markdown. Please observe the following conventions:
- Images associated with blog posts should be placed in
/static-site/public/blog/img/
- All images associated with a given blog post should start with a common filename prefix, which should be clearly related to the blog post; see the existing files in the directory for examples
- Image URLs in the post should be given in an origin-relative format; i.e., they should start with
/blog/img/
- Links to other pages and resources on
nextstrain.org
should also be given in origin-relative form; i.e., they should NOT start withhttps://nextstraing.org
, only with a/
The static documentation is automatically rebuilt every time the (parent) repo is pushed to master.
Copyright Trevor Bedford and Richard Neher.
Source code to Nextstrain is made available under the terms of the GNU Affero General Public License 3.0 (AGPL-3.0). Nextstrain is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.