AstroでWeb制作する時のTips集 🚀
Sassを使う
インストール
npm i sass
mixinを各SCSSファイルにimportする
下記を追加することで@use
でファイルを読み込まなくても全CSSファイルでstyles/_variables.scss
に記述したmixinが使えるようになる。
import { defineConfig } from "astro/config";
// https://astro.build/config
export default defineConfig({
vite: {
css: {
preprocessorOptions: {
scss: {
additionalData: '@use "src/styles/_variables.scss" as *;',
},
},
},
},
});
こんな感じ👇
.header {
margin: 0;
padding: 0 1em;
background: white;
@include mq(sm) {
display: none;
}
}
Vercelへデプロイする
Vercelアダプターのインストール
npx astro add vercel
質問に答えていく
Yes
Astro will run the following command:
If you skip this step, you can always run it yourself late
npm install @astrojs/vercel
No(SSRする場合はyes)
Astro will make the following changes to your config file:
- astro.config.mjs
import { defineConfig } from "astro/config";
import vercel from "@astrojs/vercel/serverless";
export default defineConfig({ ・・・ 省略
リポジトリをインポート
Vercelの管理画面で対象のリポジトリをインポートして、各設定をすればデプロイ完了 🎊
Taillwind CSSのインストール
コマンド
# npmの場合
npx astro add tailwind
# yarnの場合
yarn astro add tailwind
# pnpmの場合
pnpm astro add tailwind
Prettierを導入する
インストール
PrerrierとAstro用のPrettierをインストールする。
npm install prettier-plugin-astro prettier
設定ファイルをつくる
ルート直下のファイルで次の設定を行う
module.exports = {
plugins: [require.resolve('prettier-plugin-astro')],
overrides: [
{
files: '*.astro',
options: {
parser: 'astro',
},
},
],
};
pnpm を使用したときにbuildが通らないエラーの解決法
事象
pnpm buildをすると次のエラーがでる
generating optimized images
node:internal/process/promises:288
triggerUncaughtException(err, true /* fromPromise */);
^
MissingSharp: Could not find Sharp. Please install Sharp (`sharp`) manually into your project or migrate to another image service.
解決策
sharp をインストールすればビルドが通るようになる。
pnpm i sharp
何が悪かったのか?
Astroは画像処理にSharpを使用しているが、pnpmのような厳格なパッケージマネージャを使用している場合は、手動でSharpをインストールする必要がある。
参考:https://docs.astro.build/ja/reference/errors/missing-sharp/#what-went-wrong
フォントのパフォーマンスを最適化する
下記のパッケージをインストールしてフォントを読み込むことでパフォーマンスがあがる。Next.jsのフォント最適化にインスパイアされて作られたらしい。
使い方
- 依存関係をインストール
pnpm add astro-google-fonts-optimizer
-
<head>
内に埋め込む
---
+ import { GoogleFontsOptimizer } from 'astro-google-fonts-optimizer';
・・・省略
---
<head>
<meta charset="UTF-8" />
<meta name="description" content="Astro description" />
<meta name="viewport" content="width=device-width" />
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<meta name="generator" content={Astro.generator} />
+ <GoogleFontsOptimizer url="https://fonts.googleapis.com/css2family=Montserrat:ital,wght@0,100..900;1,100..900&display=swap" />
<title>{title}</title>
</head>
- CSSでフォントを指定する
body {
font-family: Montserrat, sans-serif;
}
※Tailwind CSSの時
/** @type {import('tailwindcss').Config} */
export default {
content: ['./src/**/*.{astro,html,js,jsx,md,mdx,svelte,ts,tsx,vue}'],
theme: {
extend: {
+ fontFamily: {
+ montserrat: ['Montserrat', 'sans-serif'],
+ },
},
},
・・・省略
};
@tailwind base;
@tailwind components;
@tailwind utilities;
@layer base {
html,
body {
@apply font-montserrat;
}
}
Astro Sitemapで XMLサイトマップを生成する
公式のインテグレーションがあるのでインストールする。
pnpm astro add sitemap
astro.config.mjs
にintegrations
とsite
プロパティを追記する。
import { defineConfig } from 'astro/config';
import sitemap from '@astrojs/sitemap';
export default defineConfig({
// ...
site: 'https://example.jp',
integrations: [sitemap()],
});
astro-seoを使ったメタタグの設定方法
---
import "@styles/global.css";
import { SEO } from "astro-seo";
export interface Props {
title?: string;
description?: string;
noindex?: boolean;
}
const props = Astro.props;
const BASE_TITLE = "Title";
const title = props.title ? `${props.title} | ${BASE_TITLE}` : BASE_TITLE;
const BASE_DESCRIPTION ="Base description";
const description = props.description ?? BASE_DESCRIPTION;
---
<!DOCTYPE html>
<html lang="ja">
<head>
<SEO
title={title}
description={description}
noindex={props.noindex ?? false}
charset="UTF-8"
openGraph={{
basic: {
title,
type: "website",
image: "/opengraph.png",
},
}}
extend={{
link: [{ rel: "icon", href: "/favicon.ico" }],
meta: [
{ name: "viewport", content: "width=device-width" },
{ name: "twitter:card", content: "summary_large_image" },
],
}}
/>
インポートエイリアスの設定
import
をすべて相対パスで書くのは大変なので、インポートエイリアスで絶対パスでimportする。
{
"extends": "astro/tsconfigs/base",
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@/*": ["src/*"],
"@/js/*": ["src/assets/js/*"]
}
}
}
カレントページを取得する
---
const { pathname } = Astro.url;
// pathname(URLのパス部分を表す文字列)からスラッシュ(/)によって区切られたすべての部分(サブパス)を抽出
// pathnameが ./blog/article であれば blog と article を取得する
const subpath = pathname.match(/[^\/]+/g);
// 現在アクセスされているページ(pathnameで表される)と同じであるか、またはpathnameの最初のサブパスに相当するかどうかをチェック。
const isActive = href === pathname || href === `/${subpath?.[0]}`;
---
<a href={href} class:list={["link",className, { active: isActive }]} {...props}>
Link
</a>
.active {
text-decoration: underline;
text-underline-offset: 6px;
text-decoration-thickness: 2px;
}
class:list
でclassを動的に制御する
Astro.props
からclassプロパティを取得し、それをclassNameという名前の変数に割り当て、Astroのclass:list
属性でcontainer
というクラス名と、className変数の値が含まれる配列を渡す。
<div>
要素には常にcontainer
クラスが適用され、さらにclassName変数に値があれば、そのクラスも適用されるようになる。
---
const { class: className} = Astro.props
---
<div class:list={["container", className]} {...props}>
<slot/>
</div>
<style>
.container {
max-width: 1200px;
margin-inline: auto;
}
</style>
こうすることで子コンポーネント側でのみwide
クラスにCSSを設定できる。classが空の場合はデフォルトのスタイルのみ適用される。
<Container class="wide">
<h1>Title</h1>
</Container>
transition:name
を使用する
動的ルートで前提
- AstroのView Transitions APIを利用していること
-
src/blog/[...slug].astro
のような動的ルーティングを行なっていること