Project template based on Astro.
Node.js version requirements are specified in package.json.
The project is set up to work with pnpm, which can be activated with the following command if Node.js is installed:
corepack enable
Then, install the dependencies:
pnpm i
After installing the dependencies, you can start the dev server:
pnpm start
and begin development.
Independent (as much as possible) components are located in src/components/, as an Astro single file component named in PascalCase with the appropriate extension .astro.
For component organization, follow the BEM methodology. For CSS classes, use the so-called React notation:
Example: BlockName-ElemName_modName_modValue.
Files that do not belong to a specific independent component but can be used both in and outside of components are placed in src/shared/.
All page files should be named index.astro and placed in src/pages/ in subdirectories corresponding to the route names. For example, the following source file structure:
└── src/
└── pages/
├── about/
│ └── index.astro
├── typography/
│ └── index.astro
└── index.astro
is built into:
└── dist/
├── about/
│ └── index.html
├── typography/
│ └── index.html
└── index.html
Page files should only contain the unique content markup (the content of the main tag). Everything else is marked up in the base layout src/layouts/BaseLayout.astro, which extends the page markup.
When deploying to GitHub Pages to a project subdirectory, use the normalizePath() utility for paths to work correctly at different levels of the directory structure:
---
+import { normalizePath } from "../../utils/normalizePath.js"
---
-<a href="/about">About us</a>
+<a href={normalizePath(`/about`)}>About us</a>
The individual CSS files of common styles in src/shared/ are imported into the main file src/styles/index.css, which is imported into src/layouts/BaseLayout.astro. Styles from component files Astro itself adds to the resulting style file.
└── src/
├── shared/
│ ├── global/
│ │ ├── colors.css
│ │ ├── focus.css
│ │ └── images.css
│ └── icons/
│ └── index.css
└── styles/
└── index.css # Main style file
Working with scripts is identical to working with styles, with the caveat that the main script files are located in src/scripts/.
Raster and content vector graphics (logos, charts, illustrations) should be placed in src/shared/images/.
If a raster image needs to adapt to viewport sizes, different versions of the image should be named with a numerical suffix (after the name, separated by a hyphen) corresponding to the breakpoint (viewport width from which this version should be displayed). The minimum version should remain without a breakpoint suffix.
Example of two images, each in three versions for different viewport sizes:
└── src/
└── shared/
└── images/
├── aurora-1280.png
├── aurora-640.png
├── aurora.png
├── eclipse-1280.png
├── eclipse-640.png
└── eclipse.png
Run pnpm optimize:images. By default, the command assumes these files are for double pixel density. This can be changed with the -d option, for example pnpm optimize:images -d 3. By default, the source files are converted to .webp and .avif. This can also be changed with the -f and -a options (see option descriptions).
Additionally, the command will delete the source files after conversion and create json and js metadata files. For this project, json files are not needed and can be deleted, while js files are used in the src/components/Picture.astro component. The source files above will produce the following set of final files:
└── src/
└── shared/
└── images/
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── aurora.js
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
└── eclipse.js
Thus, after conversion, to insert an adaptive image into a page, it is enough to import the Picture component and call it by passing the image name to the name attribute and specifying other necessary attributes (see examples in the page files).
For background raster images, use image-set().
Additionally, pnpm optimize:images optimizes vector images in src/shared/images/.
Place vector icons in src/shared/icons/ and run pnpm optimize:icons to optimize the icons and generate a src/shared/icons/index.css file with custom properties containing paths to these icon files.
In component styles, use these custom properties to insert the icon into a background or mask.
Place vector favicons in public/ (not in src/!). File names should be as follows:
└── public/
├── 16.svg # Special version sized 16×16.
├── 32.svg # Main version sized 32×32.
└── touch.svg # Large touch icon without roundings and transparencies.
Add 16.svg only if there is a special 16×16 version in the layout.
Run pnpm optimize:favicons to generate all necessary favicons, the web manifest, and the Links.md file with the needed link tags (copy this code into the head tag of the layout markup, after which Links.md can be deleted).
The result will be:
└── public/
├── favicons/
│ ├── icon-180.png
│ ├── icon-192.png
│ ├── icon-192.webp
│ ├── icon-512.png
│ ├── icon-512.webp
│ └── icon.svg
├── favicon.ico
└── manifest.webmanifest
If there are no special requirements for the apple-touch-icon, you can delete the public/favicons/icon-180.png file and the link referring to it.
If necessary, adjust the paths in the link tags and the web manifest.
If the project requires fonts available on FontSource, use their font npm packages:
src/shared/fonts/index.css.1em units, i.e., divide the required values by the unitsPerEm value. For example, the unitsPerEm for the Fira Code font is 2000 — divide all required values by this number:xHeight = 1050 / 2000 = 0.525capHeight = 1374 / 2000 = 0.687ascend = 1980 / 2000 = 0.99descend = 644 / 2000 = 0.322If the required fonts are not available on FontSource, use the font files provided by the designer. Place them in src/shared/fonts/, but you'll need to define @font-face in src/shared/fonts/index.astro manually.
All font files are placed in dist/fonts/ during the build.
In the project's deployment scripts, use pnpm build to build the project into dist.
If deploying to a server subdirectory, pass the subdirectory name to base option in astro.config.js.
The project is already set up with a GitHub Action for deploying to GitHub Pages with the ability to deploy to a project subdirectory. The action automatically passes the project name as the subdirectory name to the base option by calling the getProjectRoot() utility.