Xây dựng CMS với Supabase và React trong 7 bước đơn giản

04/04/2026 P T P Chung 8 phút đọc 0 bình luận

Giới thiệu

Trong bối cảnh hiện nay, việc quản lý nội dung trên web đã trở thành một phần không thể thiếu đối với hầu hết các doanh nghiệp và cá nhân. Một hệ thống quản lý nội dung (CMS) mạnh mẽ không chỉ giúp tổ chức thông tin một cách khoa học, mà còn hỗ trợ người dùng không chuyên vẫn có thể dễ dàng cập nhật và điều chỉnh nội dung. Supabase, với khả năng cung cấp backend realtime và PostgreSQL, kết hợp cùng React - một trong những thư viện frontend phổ biến nhất, tạo nên một cặp đôi đáng tin cậy cho việc xây dựng một CMS hiện đại.

Vì sao chọn Supabase và React?

Supabase được ví như một "alternative" của Firebase, nhưng với lợi thế sử dụng PostgreSQL làm cơ sở dữ liệu chính. Điều này mang lại khả năng truy vấn mạnh mẽ và linh hoạt hơn. Ngoài ra, Supabase còn cung cấp Authentication, Storage, và Row Level Security (RLS), giúp bảo mật dữ liệu ngay từ tầng cơ sở.

Trong khi đó, React nổi tiếng với khả năng xây dựng giao diện người dùng nhanh chóng và dễ dàng mở rộng. Kết hợp với Supabase, bạn có thể tập trung vào trải nghiệm người dùng mà không cần lo lắng quá nhiều về backend.

Thiết lập dự án

Để bắt đầu, bạn cần khởi tạo một dự án Supabase mới trên dashboard của họ. Sau khi có database và các thông tin kết nối, hãy tạo một dự án React bằng lệnh:

npx create-react-app cms-supabase
cd cms-supabase

Tiếp theo, cài đặt thư viện Supabase:

npm install @supabase/supabase-js

Thiết kế cơ sở dữ liệu

Một CMS cơ bản thường có các bảng như: users, posts, categories, comments. Trong Supabase, bạn có thể tạo các bảng này thông qua SQL Editor hoặc UI. Ví dụ, bảng posts có thể có các cột:

- id (UUID) - title (text) - content (text) - category_id (UUID) - created_at (timestamp) - updated_at (timestamp)

Để bảo mật, bạn nên thiết lập Row Level Security. Bắt đầu bằng cách kích hoạt RLS:

alter table posts enable row level security;

Sau đó, tạo các policy để chỉ cho phép tác giả xem/sửa/xóa bài viết của mình:

create policy "Users can view own posts" on posts
  for select using (auth.uid() = user_id);

create policy "Users can insert own posts" on posts for insert with check (auth.uid() = user_id);

create policy "Users can update own posts" on posts for update using (auth.uid() = user_id);

create policy "Users can delete own posts" on posts for delete using (auth.uid() = user_id);

Xây dựng frontend với React

Khởi tạo kết nối Supabase trong một file riêng, ví dụ supabaseClient.js:

import { createClient } from '@supabase/supabase-js';

const supabaseUrl = process.env.REACT_APP_SUPABASE_URL; const supabaseAnonKey = process.env.REACT_APP_SUPABASE_ANON_KEY;

export const supabase = createClient(supabaseUrl, supabaseAnonKey);

Tạo một component đơn giản để đăng nhập:

Quảng cáo

300x250 In-Content Advertisement

import { useState } from 'react';
import { supabase } from './supabaseClient';

function Auth() { const [email, setEmail] = useState(''); const [password, setPassword] = useState('');

const handleSignIn = async () => { const { data, error } = await supabase.auth.signInWithPassword({ email, password, }); if (error) console.log(error); };

return ( <div> <input value={email} onChange={e => setEmail(e.target.value)} /> <input type="password" value={password} onChange={e => setPassword(e.target.value)} /> <button onClick={handleSignIn}>Đăng nhập</button> </div> ); }

Để quản lý bài viết, bạn có thể tạo một component PostManager để hiển thị danh sách và thêm/sửa/xóa:

import { useState, useEffect } from 'react';
import { supabase } from './supabaseClient';

function PostManager() { const [posts, setPosts] = useState([]); const [title, setTitle] = useState(''); const [content, setContent] = useState('');

useEffect(() => { fetchPosts(); const subscription = supabase .from('posts') .on('*', () => fetchPosts()) .subscribe(); return () => supabase.removeSubscription(subscription); }, []);

const fetchPosts = async () => { let { data: posts, error } = await supabase .from('posts') .select('*'); if (error) console.error(error); else setPosts(posts); };

const createPost = async () => { const { error } = await supabase .from('posts') .insert([{ title, content, user_id: supabase.auth.user().id }]); if (error) console.error(error); };

return ( <div> <h2>Quản lý bài viết</h2> <input value={title} onChange={e => setTitle(e.target.value)} /> <textarea value={content} onChange={e => setContent(e.target.value)} /> <button onClick={createPost}>Thêm bài viết</button> <ul> {posts.map(post => ( <li key={post.id}>{post.title}</li> ))} </ul> </div> ); }

Nâng cao trải nghiệm người dùng

Để cải thiện trải nghiệm, bạn có thể thêm tính năng tìm kiếm, phân trang, và upload hình ảnh vào bài viết. Supabase Storage sẽ hỗ trợ bạn lưu trữ file một cách an toàn. Ví dụ, upload hình ảnh:

const uploadImage = async (file) => {
  const fileExt = file.name.split('.').pop();
  const fileName = ${Math.random()}.${fileExt};
  const filePath = ${supabase.auth.user().id}/${fileName};

const { data, error } = await supabase.storage .from('images') .upload(filePath, file);

return data; };

Kết luận

Việc xây dựng một CMS với Supabase và React không chỉ giúp bạn tiết kiệm thời gian phát triển, mà còn đảm bảo tính bảo mật và khả năng mở rộng cho dự án. Supabase với PostgreSQL mạnh mẽ, kết hợp cùng sự linh hoạt của React, tạo nên một giải pháp toàn diện cho nhu cầu quản lý nội dung hiện đại. Hãy bắt tay vào thực hành và tùy biến theo nhu cầu của riêng bạn, để tạo ra một CMS phù hợp nhất với dự án của mình.

Quảng cáo

728x90 Bottom Advertisement

Thay thế bằng mã Google AdSense

Chia sẻ bài viết

Facebook Twitter

Bình luận

Chia sẻ ý kiến của bạn về bài viết này

Viết bình luận

Bình luận của bạn sẽ được kiểm duyệt trước khi hiển thị

Chưa có bình luận nào

Hãy là người đầu tiên bình luận về bài viết này!