It's me ;-)

Giải pháp đơn giản cho việc hỗ trợ SEO/Sharing trên Single Page App

Chẳng là đợt này có mấy dự án ở công ty đều dính cùng 1 vấn đề, đó là chạy SPA (single page application) bằng ReactJS nhưng có đoạn yêu cầu khi paste link vào các social network hay Skype/Telegram… thì phải hiển thị được cái share preview đó 😂

Thật ra nếu ban đầu mà biết có vụ này thì xài luôn SSR (Server side render) cho rồi, như NextJS chẳng hạn. Nhưng giờ dự án chạy cũng được mấy tháng rồi, giờ mà chuyển thì cũng vỡ mồm 😭

Để giải quyết vụ này mà không dùng SSR thì tạm thời mình biết có 2 cách:

  1. Thêm 1 layer nữa (chạy server side) để inject các thẻ meta của Open Graph Protocol/Twitter card vào file index.html, sau đó mới trả về cho trình duyệt
  2. Sử dụng các service của bên thứ ba, ví dụ như prerender.io

Ở đây mình chọn cách 1. Cách bước thực hiện rất đơn giản:

1. Xác định các mục cần xử lý “động” (generate meta tags by content)

Như các bạn thấy thì mình để sẵn các giá trị:

  • __META_DESCRIPTION__: Placeholder dùng cho nội dung mô tả
  • __META_TWITTER_TITLE__: Placeholder dùng cho title hiển thị trên Twitter
  • __META_TWITTER_DESCRIPTION__: Placeholder dùng cho nội dung mô tả hiển thị trên Twitter
  • __META_TWITTER_IMAGE__: Placeholder dùng cho ảnh hiển thị trên Twitter
  • __META_OG_TITLE__: Placeholder dùng cho title hiển thị trên Facebook và các nền tảng sử dụng Open Graph Protocol
  • __META_OG_DESCRIPTION__: Placeholder dùng cho nội dung mô tả hiển thị trên Facebook và các nền tảng sử dụng Open Graph Protocol
  • __META_OG_IMAGE__: Placeholder dùng cho ảnh hiển thị trên Facebook và các nền tảng sử dụng Open Graph Protocol

2. Viết code xử lý (server side) request, inject/replace thông tin tương ứng cho các thẻ meta

Chỗ này thì mình xài NodeJS + Express cho lẹ, tư tưởng cũng rất đơn giản:

  • Nếu là static resource thì trả về như bình thường, không xử lý gì
  • Còn là request không phải static resource thì tóm hết lại
    • Kiểm tra xem có phải page mình mong muốn hỗ trợ inject/replace các thẻ Meta không?
      • Nếu đúng thì xử lý bóc tách ID rồi lấy thông tin tương ứng ra rồi replace thôi
      • Còn nếu không đúng thì trả về default. Chỗ này các bạn có thể xử lý thêm content default, code của mình dạng POC thôi nên… kệ 🤣

Vậy là xong, code React build xong thì quẳng vào folder build, rồi code NodeJS thì wrap bên ngoài vậy thôi:

Với cách tiếp cận này thì FE gần như không phải sửa gì cả, tuy nhiên BE cần code thêm 1 chút, cũng không quá nhiều nếu như bạn chỉ có 1 v ài page cần share/seo

Nhược điểm thì cũng có:

  • Chạy chậm hơn, do ban đầu là SPA, mọi thứ là static file, chỉ cần NGINX là chạy tít. Giờ cần nhồi thêm 1 layer nữa nên chắc chắc performance sẽ bị chậm
  • Phải sửa lại flow của CI/CD, do cách tổ chức code cũng thay đổi như ở ảnh folder structure bên trên

Tạm thế này, bao giờ áp dụng vào production mình sẽ cập nhật tiếp xem có phát sinh thêm vấn đề gì không 😅

Leave a Reply

Your email address will not be published. Required fields are marked *