😎

AstroでWeb制作する時のTips

2024/04/10に公開

Sassを使う

インストール

npm i sass

mixinを各scssファイルにimportする

次のコードをastro.config.mjsに追加することで、毎回@useでファイルを読み込まなくても、すべてのscssファイルでmixinなどが使えるようになる。
次の例だと、styles/_variables.scssに記述したmixinがすべてのscssファイルで使えるようになる。

astro.config.mjs
import { defineConfig } from "astro/config";

// https://astro.build/config
export default defineConfig({
  vite: {
+   css: {
+     preprocessorOptions: {
+       scss: {
+         additionalData: '@use "src/styles/_variables.scss" as *;',
+       },
+     },
+   },
  },
});

@useでインポートしなくても使用できる ✨

Menu.astro
.menu {
    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のインストール

https://docs.astro.build/ja/guides/integrations-guide/tailwind/

コマンド

# npmの場合
npx astro add tailwind

# yarnの場合
yarn astro add tailwind

# pnpmの場合
pnpm astro add tailwind

Prettierを導入する

インストール

PrettierとAstro用のPrettierのプラグインをインストールする。

npm install prettier-plugin-astro prettier

設定ファイルをつくる

ルート直下に次のファイルを作って設定を行う

.prettierrc.cjs
module.exports = {
  plugins: [require.resolve('prettier-plugin-astro')],
  overrides: [
    {
      files: '*.astro',
      options: {
        parser: 'astro',
      },
    },
  ],
};

NPMスクリプトを追加

package.json
{
    "scripts": {
    "dev": "astro dev",
    "start": "astro dev",
    "build": "astro build",
    "preview": "astro preview",
    "astro": "astro",
+   "prettier": "prettier --write 'src/**/*.{ts,js,astro,css,scss}'",
  },
}

保存時に自動整形する

.vscode/settings.json
{
  "editor.formatOnSave": true
}

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.

解決法

Astroは画像処理にSharpを使用しているが、pnpmのような厳格なパッケージマネージャを使用している場合は、手動でSharpをインストールする必要がある。

pnpm i sharp

https://docs.astro.build/ja/reference/errors/missing-sharp/#what-went-wrong

フォントのパフォーマンスを最適化する

下記のパッケージをインストールしてフォントを読み込むことでパフォーマンスがあがる。
Next.jsのフォント最適化にインスパイアされて作られたらしい。

https://github.com/sebholstein/astro-google-fonts-optimizer

使い方

  1. インストール
pnpm add astro-google-fonts-optimizer
  1. <head>内に埋め込む
layout.astro
---
+ 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>
  1. CSSでフォントを指定する
global.css
body {
    font-family: Montserrat, sans-serif;
}
Tailwind CSSの場合
tailwind.config.js
/** @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'],
+    },
    },
  },
 ・・・省略
};
global.css
@tailwind base;
@tailwind components;
@tailwind utilities;

@layer base {
  html,
  body {
    @apply font-montserrat;
  }
}

Astro Sitemapで XMLサイトマップを生成する

公式のインテグレーションがあるのでインストールする。
https://docs.astro.build/en/guides/integrations-guide/sitemap/

pnpm astro add sitemap

astro.config.mjsintegrationssiteプロパティを追記する。

astro.config.mjs
import { defineConfig } from 'astro/config';
import sitemap from '@astrojs/sitemap';

export default defineConfig({
  // ...
  site: 'https://example.jp',
  integrations: [sitemap()],
});

インポートエイリアスの設定

importをすべて相対パスで書くのは大変なので、インポートエイリアスで絶対パスでimportできるようにする。

https://docs.astro.build/ja/guides/aliases/

tsconfig.json
{
  "extends": "astro/tsconfigs/base",
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "@/*": ["src/*"],
      "@/js/*": ["src/assets/js/*"]
    }
  }
}

カレントページを取得する

グローバルナビゲーションなどで使用する、現在のページの時にハイライトさせる方法。

src/components/NavLink.astro
---
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>

<style lang="scss">
  .active {
    text-decoration: underline;
    text-underline-offset: 6px;
    text-decoration-thickness: 2px;
  }
</style>

親コンポーネントでNavLinkコンポーネントを呼びだして使用する。

src/components/Header.astro
---
import NavLink from './NavLink.astro'
---

<header class="header">
  <nav class="nav">
    <a href="/" class="logo">LOGO</a>
    <div class="links">
      <div class="internal-links">
        <NavLink href="/">HOME</NavLink>
        <NavLink href="/blog">BLOG</NavLink>
        <NavLink href="/contact">CONTACT</NavLink>
      </div>
    </div>
  </nav>
</header>

<style lang="scss">
  .links {
    display: flex;
    align-items: center;
  }
</style>

class:listでclassを動的に制御する

Astro.propsからclassプロパティを取得し、それをclassNameという名前の変数に割り当て、Astroのclass:list属性でcontainerというクラス名と、className変数の値が含まれる配列を渡す。

<div>要素には常にcontainerクラスが適用され、さらにclassName変数に値があれば、そのクラスも適用されるようになる。

src/components/Container.astro
---
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が空の場合はデフォルトのスタイルのみ適用される。

index.astro
<Container class="wide">
    <h1>Title</h1>
</Container>

Markdownでファイル名表示や差分表示をする

AstroではシンタックスハイライターとしてShikiがデフォルトで有効になっているが、Shikiだけではファイル名の表示やコードの差分表示等に対応していない。
Expressive Codeをインストールすることで、上記の機能やクリップボードへのコピーなどの機能が自動で使用できるようになる。

下記でパッケージをインストール後にastro.config.mjsにプラグインの記述を追加するだけでマークダウンの機能が拡張される。

pnpm add astro-expressive-code
astro.config.mjs
import mdx from '@astrojs/mdx'
import { defineConfig } from 'astro/config'
import rlc from 'remark-link-card'
+ import expressiveCode from 'astro-expressive-code'

// https://astro.build/config
export default defineConfig({
  site: 'https://example.com',
+ integrations: [expressiveCode(), mdx()],
  markdown: {
    shikiConfig: {
      theme: 'github-dark-dimmed',
    },
    remarkPlugins: [rlc],
  },
})

GitHubで編集を提案

Discussion