🎧 Tại Sao Nên Thêm Widget Spotify?
Một trang portfolio không chỉ là một trang tĩnh — những chi tiết cá nhân nhỏ có thể làm nó nổi bật hơn. Một widget nghe nhạc gần đây của Spotify làm điều đó:
- Giúp portfolio của bạn trở nên sống động — hiển thị những gì bạn đang nghe ngay bây giờ.
- Thêm phần cá tính. Nhà tuyển dụng, khách hàng hoặc các nhà phát triển khác sẽ có cái nhìn về gu âm nhạc của bạn.
- Nó mang tính động. Khác với văn bản tĩnh, widget tự động cập nhật bất cứ khi nào bạn phát nhạc trên Spotify.
Thay vì chỉ nói “Tôi tạo ra những thứ thú vị với Astro”, trang của bạn còn nói, “Đây là những gì tôi đã nghe tối qua khi lập trình.”
🛠️ Bạn Sẽ Xây Dựng Gì
Cuối cùng của hướng dẫn này, bạn sẽ có một widget:
✅ Kết nối với Web API của Spotify
✅ Lấy track đã nghe gần đây theo thời gian thực
✅ Hiển thị ảnh bìa album, tên bài hát và thông tin nghệ sĩ
✅ Chạy với một endpoint server an toàn của Astro
⚡ Tóm Tắt Nhanh
- Lấy thông tin xác thực API của Spotify.
- Sử dụng Bruno để tạo refresh token.
- Tạo một endpoint API của Astro để lấy dữ liệu từ Spotify.
- Hiển thị widget trong portfolio của bạn.
📋 Điều Kiện Cần Có
Đảm bảo bạn đã có:
- Node.js và npm đã được cài đặt
- Tài khoản nhà phát triển Spotify – cần thiết để đăng ký ứng dụng và lấy thông tin xác thực.
- Một Bruno API Client (để xử lý luồng OAuth một cách dễ dàng)
- Kiến thức cơ bản về các dự án Astro
💡 Nếu bạn chưa bao giờ sử dụng Bruno trước đây, hãy nghĩ rằng đây là một lựa chọn hiện đại cho Postman. Nhẹ nhàng, mã nguồn mở, và hoàn hảo cho việc thử nghiệm API.
🚀 Bước 1 — Tạo Một Dự Án Astro Mới
Nếu bạn chưa có:
npm create astro@latest my-spotify-portfolio
cd my-spotify-portfolio
npm install
Cấu trúc dự án của bạn sẽ như sau:
/
├── src/
│ ├── components/
│ ├── layouts/
│ ├── pages/
│ └── content/
├── public/
└── astro.config.mjs
🔐 Bước 2 — Xác Thực Với Spotify Qua Bruno
Spotify yêu cầu OAuth 2.0 Authorization Code Flow.
Đối với widget portfolio, chúng ta không muốn người dùng phải đăng nhập — vì vậy chúng ta sẽ sử dụng refresh token.
Dưới đây là cách thực hiện:
- Mở Bruno và tạo một yêu cầu mới.
- Dưới Auth → OAuth 2.0 → Authorization Code, điền vào:
- Callback URL:
http://localhost:3000/callback - Authorization URL:
https://accounts.spotify.com/authorize - Access Token URL:
https://accounts.spotify.com/api/token - Client ID / Secret: từ ứng dụng Spotify của bạn
- Scope:
user-read-recently-played
- Nhấn Get New Access Token. Bruno sẽ cung cấp cho bạn cả
access_token(ngắn hạn) vàrefresh_token(dài hạn).
✅ Lưu refresh_token — chúng ta sẽ sử dụng nó ở bước tiếp theo.
🧠 Bước 3 — Tạo Một Endpoint Server Astro
Endpoints server của Astro hoạt động như các tuyến backend trong dự án của bạn — không cần hàm serverless bên ngoài.
Đầu tiên, tạo một tệp .env:
SPOTIFY_CLIENT_ID=your_client_id
SPOTIFY_CLIENT_SECRET=your_client_secret
SPOTIFY_REFRESH_TOKEN=your_refresh_token
Bây giờ tạo tuyến API của bạn:
// src/pages/api/spotify-recently-played.ts
export const prerender = false;
import type { APIRoute } from "astro";
export const GET: APIRoute = async () => {
const client_id = import.meta.env.SPOTIFY_CLIENT_ID!;
const client_secret = import.meta.env.SPOTIFY_CLIENT_SECRET!;
const refresh_token = import.meta.env.SPOTIFY_REFRESH_TOKEN!;
try {
// 1. Lấy một access token mới
const tokenResponse = await fetch("https://accounts.spotify.com/api/token", {
method: "POST",
headers: {
"Content-Type": "application/x-www-form-urlencoded",
Authorization: "Basic " + Buffer.from(client_id + ":" + client_secret).toString("base64"),
},
body: new URLSearchParams({
grant_type: "refresh_token",
refresh_token,
}),
});
const tokenData = await tokenResponse.json();
if (!tokenResponse.ok) throw new Error(tokenData.error_description);
const access_token = tokenData.access_token;
// 2. Lấy track đã nghe gần đây
const recentRes = await fetch(
"https://api.spotify.com/v1/me/player/recently-played?limit=1",
{ headers: { Authorization: `Bearer ${access_token}` } }
);
const recentData = await recentRes.json();
const latest = recentData.items?.[0]?.track;
if (!latest) {
return new Response(JSON.stringify({ error: "Không tìm thấy track gần đây" }), { status: 404 });
}
// 3. Gửi phản hồi JSON sạch
return new Response(
JSON.stringify({
albumCover: latest.album.images[0]?.url || null,
song: latest.name,
artist: latest.artists.map((a: any) => a.name).join(", "),
spotifyUrl: latest.external_urls.spotify,
}),
{ status: 200, headers: { "Content-Type": "application/json" } }
);
} catch (err: any) {
return new Response(JSON.stringify({ error: err.message }), { status: 500 });
}
};
Giờ đây, khi truy cập /api/spotify-recently-played sẽ trả về track đã nghe gần đây của bạn dưới dạng JSON.
🎨 Bước 4 — Tạo Widget Spotify
Cuối cùng, hãy xây dựng giao diện người dùng. Bạn có thể lấy một widget khởi đầu tại đây:
Sao chép mã vào src/components/SpotifyWidget.astro và cập nhật URL fetch nếu cần.
✅ Kết Luận
Bạn vừa xây dựng một widget nghe nhạc gần đây của Spotify bằng các endpoint server của Astro và Spotify Web API.
Tính năng nhỏ này cho thấy rằng bạn:
- Hiểu về luồng OAuth
- Có thể tạo endpoints backend an toàn trong Astro
- Biết cách tích hợp API bên thứ ba vào dự án của bạn
Đây là một chi tiết nhỏ — nhưng là một chi tiết làm cho portfolio của bạn sống động và cá nhân hơn.
📚 Để biết thêm thông tin chi tiết, hãy tham khảo hướng dẫn chính thức về Luồng Xác Thực của Spotify.