Laravel+ReactのサイトにZennのブログを表示させる
LaravelでWebアプリを作るにあたり、まずは所感を掴むためにコーポレートサイトのリニューアルをしました。
そこで今回のZennのTechブログをコーポレートサイトでも表示できるようにしたいと思います。
環境
- PHP 8.3.12 (cli) (built: Sep 24 2024 18:08:04) (NTS)
- Laravel Framework 11.33.2
- react 18.2.0
- typescript 5.6.3
- tailwindcss 3.2.1
- Breeze
参考サイト
Zennの投稿を取得してブログに取り込む(※Next.js)
Day.jsの使い方・まとめ Zenn API Types手順
ブログ表示用のページ、日付変換用のページ、web.phpでURLの認証が必要です。
1.自分のURLの確認
Zennの記事一覧は下記のURLを確認します。
https://zenn.dev/api/articles?username=【ここに自分のユーザーネーム】&order=latest
自分のユーザーネームはここで確認できます。
2.BlogList.tsxを作成
ページタイトルはコンポーネントにしているので、参考にする人は適宜h1タグなどに書き換えてください。
import { useState, useEffect } from 'react';
import Title from '../PageTitle';
import ConvertDate from './ConvertDate';
export type ZennItem = {
id: number; // 記事ID
title: string; // 記事タイトル
emoji: string; // 記事に関連付けられた絵文字
path: string; // 記事のURLパス
published_at: string; // 公開日時 (ISO8601)
};
// 全体レスポンスの型
export type ZennResponse = {
articles: ZennItem[]; // 記事のリスト
};
export default function BlogList() {
const [posts, setPosts] = useState<ZennItem[]>([]);
const [visibleIndexes, setVisibleIndexes] = useState<number[]>([]);
useEffect(() => {
const fetchData = async () => {
try {
const res = await fetch('/zenn/articles');
const data: ZennResponse = await res.json(); // 型を明示
setPosts(data.articles.slice(0, 10)); // 記事リストを保存
} catch (error) {
console.error('データ取得エラー:', error);
}
};
fetchData();
}, []);
return (
<>
<Title title="blog" />
<p className='text-center'>ZennにてTechブログ記載しています。<br />Xでは日常の感想が多いけど、気軽にお話しできる仕事仲間を募集中です。</p>
<div className="h-auto w-[calc(100%-16px)] mx-auto flex flex-row flex-wrap gap-2">
{posts.map((post, index) => (
<article
key={post.id}
className="w-full h-auto md:w-[calc(50%-4px)] bg-slate-200"
>
<a
href={`https://zenn.dev/${post.path}`}
target="blank"
rel="noopener noreferrer"
className="group border-spacing-0.5 flex flex-col gap-2 w-full h-auto px-4 py-2"
>
<h2 className="text-2xl group-hover:text-primary">{post.title}</h2>
<ConvertDate convertDate={post.published_at} />
</a>
</article>
))}
</div>
</>
);
}
3.ConvertDate.tsxを作成
日付をスラッシュで区切る(YYYY/MM/DD)より、ハイフンで区切った方(YYYY-MM-DD)が好みなので、書き換えます。
なんだそのこだわり知らんわって方は飛ばしてください。
import dayjs from 'dayjs';
type Props = {
convertDate: string | number | Date;
};
export default function ConvertDate({ convertDate }: Props) {
const publishedAt = dayjs(convertDate).format('YYYY-MM-DD');
return <time dateTime={convertDate.toString()} className='ext-sm block text-slate-500'>{publishedAt}</time>;
}
4.routes/web.phpで通信設定
Laravelの場合はCORS制限が引っかからないようにroutes/web.phpに表示させたいURLを記載させなければいけません。
use Illuminate\Support\Facades\Http;
Route::get('/zenn/articles', function () {
$response = Http::get('https://zenn.dev/api/articles?username=【ここに自分のユーザーネーム】&order=latest');
return response()->json($response->json());
});
5.自分に必要な項目は下記から適宜取得
すごいありがたいファイルを作成してくれている方がいたので、型など参考にしてください。
export type Article = {
id: number;
post_type: "Article";
title: string;
slug: string;
published: boolean;
comments_count: number;
liked_count: number;
body_letters_count: number;
article_type: "tech" | "idea";
emoji: string;
is_suspending_private: boolean;
published_at: string;
body_updated_at: string;
source_repo_updated_at: string;
path: string;
user: User;
publication: Publication | null;
};
上記以外にもUserの型一覧やPublicationの型一覧を書いてくださってます。
自分サイトに合わせて記載するのもアリですね。
Discussion