Project template based on Astro and Svelte.
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 or Svelte single file component named in PascalCase with the appropriate extension .astro
or .svelte
.
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.