| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Name | Name | Last commit date | ||
|---|---|---|---|---|
Code for the Bgee website available at https://www.bgee.org. Bgee is a database for retrieval and comparison of gene expression patterns across multiple animal species.
This website uses React Router 7 to serve pages with server-side rendering (SSR).
Requirements: we recommend using the latest NodeJS LTS (22+), but anything after 18 should work.
Install dependencies:
npm iNote
This will automatically setup git pre-commit hooks to run formatter, linter and type checker on every commit and make sure the commited code is in good shape.
Tip
Alternatively, install dependencies without running the script to install playwright for tests:
npm i --ignore-scriptsStart development server at http://localhost:5173
npm run devFormat and lint with prettier and eslint:
npm run fmtCheck types with TypeScript:
npm run typecheckNote
Formatting and type checking will be run automatically when you commit with husky and lint-staged.
Run the tests with playwright:
npm testRun everything (format, type check, tests):
npm run allUpgrade dependencies to their latest available version in the package.json file:
npm run upgradeCheck libraries to update
npm outdatedWarning
bulma breaks when upgraded to v1+, the rest can be usually upgraded without problem. It has been excluded from the upgrade script.
Create a production build:
npm run buildStart the production server:
npm startMake sure to deploy the output of npm run build
├── package.json ├── package-lock.json ├── build/ │ ├── client/ # Static assets │ └── server/ # Server-side code
Prepare the application to be deployed as an archive:
npm run archiveImportant
Be careful with the version set in config.json, it will impact the app in production or in archive.
Build:
docker build -t bgee-web .Run:
docker run -p 3000:3000 bgee-webWith pm2, build, then deploy with a load balancer on http://localhost:3000/
npm run build
npm run clusterCheck logs:
npm run logsStop all processes:
npm run stop:allRun stresstest (after starting the cluster in development):
npm run stresstest2 routing approaches are available:
When creating a new route the file resolving this route can contain special exported functions used for SSR:
Important
When creating new files only create .ts or .tsx files, they provide much more help through IDE completion and reliability than .js files.
Here is an example where we make multiple API calls in parallel in the loader, and use its results to define the page metadata and page content:
import api from '~/api';
import config from '~/config.json';
import PATHS from '~/paths/paths';
import { geneToLdJSON } from '~/helpers/schemaDotOrg';
import { getMetadata } from '~/helpers/metadata';
/** Function executed on the server to render the DOM using the data retrieved */
export async function loader({ params, request }) {
try {
const [genesResp, speciesResp] = await Promise.all([
api.search.genes.getGeneralInformation(params.geneId),
api.search.species.name(params.speciesId),
]);
return {
genes: genesResp.data.genes,
species: speciesResp.data.species,
requestUrl: request.url,
};
} catch (error: any) {
throw new Response(error.data?.message || error.message || 'Page not found', { status: 404 });
}
}
/** Define the metadata of the page, can use data retrieved in the loader */
export function meta({ data }) {
return getMetadata({
title: `${data.genes.name} expression in ${data.species.name}`,
description: `Gene expression for ${data.genes.name} in ${data.species.name}`,
keywords: `gene expression, ${data.genes.name}, ${data.species.name}`,
link: data.requestUrl,
schemaorg: [geneToLdJSON(data.genes)],
});
}
/** The component for the page, can use data retrieved in the loader */
export default function Page({ loaderData }) {
const { genes, species } = loaderData;
return <GeneDisplay genes={genes} species={species} />;
}Important
Try to avoid using too many useEffect with different dependency arrays, it can trigger many rerenders, and it gets quite complex to understand what is happening. Instead prefer loading as much data as possible from the loader function, especially for static content like a gene page.
For search pages with a lot of dynamic elements, like raw-data, you will still need to use useEffect, but do it with parsimony, if you have more than 3 of them, then you're probably doing something wrong.
To add a markdown page you will need to create a new route in src/routes/ with a .tsx file, import the .md, and define the metadata in the route file, e.g.:
import { getMetadata } from '~/helpers/metadata';
import Markdown from '~/markdown/support/data-curation/data-curation.md';
export function meta() {
return getMetadata({
title: 'Bgee data curation tutorial',
description: 'Bgee Tutorial about data curation and annotation',
keywords: 'Tutorial, data curation, annotation',
});
}
export default function Page() {
return <Markdown />;
}The images are stored externally of the project. You will find the path of the images in the src/config.json file at the key imageDomain. Be careful, the image used for the 'external icon' link is directly defined in the SCSS. If you are moving it, don't forget to change the path.
If you need to add new icons you can find them there: https://lucide.dev/icons and use them like that:
import { ChevronDown } from 'lucide-react';
<ChevronDown size={15} color="black" fill="white" />;$size-7: 12px; $size-6: 1rem (= 14px) $size-5: 1.1rem (= 15.4px) $size-4: 1.2rem (= 16.8px) $size-3: 1.5rem (= 21px)
| Back | FazBrowse Home | New Git URL |