Astroでサイトを作ろう



今回はNASAのAPIを叩いて指定した日の衛星写真を見るというサイトを作成してみました。
https://api.nasa.gov/

今回使用したバージョンなど
- node 18.18.0
- astro 4.0.0
- react 18.0.0
- react-dom 18.0.0
- swr 2.2.4
- tailwindcss 3.0.24

### セットアップ
```
npm create astro@latest

npm run dev
```
ここでしっかりサイトが見れれば成功です。

### JSフレームワークとtailwindcssの追加
今回はJSフレームワークにReact、CSSはtailwindcssを使っていきます。
```
npx astro add react tailwind
```

```js astro.config.js
import { defineConfig } from 'astro/config';

import react from "@astrojs/react";
import tailwind from "@astrojs/tailwind";

export default defineConfig({
  integrations: [react(), tailwind()]
});
```
このようなコードが入力されていれば準備完了です。

```jsx:src/pages/index.astro
---
import Layout from '~/layouts/Layout.astro'
---
<Layout　title="Welcome!!">
  <h1 class="text-center mt-10">衛星写真を見てみよう</h1>
</Layout>
```

```jsx:src/layouts/Layout.astro
---
interface Props {
  title: string;
}

const { title } = Astro.props;
---
<!doctype html>
<html lang="ja">
  <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} />
    <title>{title}</title>
  </head>
  <body>
    <slot />
  </body>
</html>
```

pagesフォルダの中のindex.astroからlayoutsフォルダのLayout.astroにtitleを渡して、index.astroのchildrenがLayout.astroの **slotタグ** に入るということになります。
一回レイアウトを作ってしまえば使い回せるので便利です。

### APIKEYの取得
```.env
PUBLIC_API_KEY = {取得したAPIキー}
```
https://docs.astro.build/ja/guides/environment-variables/
クライアントサイドで読み込むので先頭に PUBLIC_ を付けてあげるようにしましょう。

### APIを叩いてみる
```tsx src/library/GetNewData.tsx
import {useState} from 'react'
import useSWR from 'swr'
import axios from 'axios'

const api_key = import.meta.env.PUBLIC_API_KEY

let today = new Date()

const GetNewData = () => {
  //初期値を昨日の日付に設定
  let stringToday = `${today.getFullYear()}-${today.getMonth()+1}-${today.getDate()-1}`
  const [date, setDate] = useState<string>(stringToday);
  const onChangeDate = (e:any) => {
   setDate(e.target.value)
  }

  const fetchWeatherData = async() => {
    const url = `https://api.nasa.gov/planetary/apod?api_key=${api_key}&date=${date}`
    const res = await axios.get(url)
    const data = res.data
    return data;
  }

  // keyを使うことでその都度読み込むURLの変化を認知
  const {data,error,isLoading} = useSWR(['/',date],fetchWeatherData);

  if (error) return <div>エラーが発生しました</div>
  if (isLoading) return <div>読み込み中...</div>

  return (
    <div className='mt-10 flex flex-col gap-8 justify-center items-center'>

     <div>
      <input 
       type='date' 
       min="2000-01-01" 
       max={stringToday}
       value={date}
       onChange={(e)=>onChangeDate(e)}
      />
     </div>

     {data.hdurl?(
      <>
       <img 
       src={data.url}
       className='w-1/2 h-1/3 rounded-lg'
       />

       <p className='px-16'>{data.explanation}</p>

      </>
      ): 
       <div>
        画像がありません
       </div>
     }
    </div>
  )
}

export default GetNewData

```
今回はlibraryフォルダを用いましたが画面を実装してしまっているので本当はcomponentsフォルダの中に書いた方が良いと思います、、、

### Astroファイルで読み込む
```jsx:index.astro
---
import Layout from '~/layouts/Layout.astro'
import GetNewData from '~/libs/GetNewData';
---
<Layout title="Welcome!!">
  <h1 class="text-center mt-10">衛星写真を見てみよう</h1>
  <GetNewData client:only="react"/>
</Layout>
```
UIフレームワークを読み込む際はこのように client:only="name" 書きます。
AstroはJSを基本排除してしまうので何も書かないとJSが動きません。
https://docs.astro.build/ja/core-concepts/framework-components/

### デプロイ
今回はnetlifyを使用しました。
https://docs.astro.build/ja/guides/deploy/netlify/
手順通りにやっていけば大丈夫だと思います。

**環境変数をしっかり設定してあげましょう**
netlifyのDeployからEnvironment variables → Add a variable → Add a single variable
ここに取得したAPI_KEYとPUBLIC_で始まる環境変数を入力。

#### 参考サイト

astroドキュメント
- https://docs.astro.build/ja/install/auto/

swrを使用したデータ取得例
- https://blog.microcms.io/astro-search/

swrドキュメント
- https://swr.vercel.app/ja/docs/getting-started

#### 終わりに

短いですが読んでいただきありがとうございました、まだプログラミングを始めて間もないので間違いなどがございましたらご指摘いただけると幸いです。