ReactJS: Cách cấu hình thẻ meta và title động trong React với Helmet và với server Node.js

Các khóa học qua video:
Python SQL Server PHP C# Lập trình C Java HTML5-CSS3-JavaScript
Học trên YouTube <76K/tháng. Đăng ký Hội viên
Viết nhanh hơn - Học tốt hơn
Giải phóng thời gian, khai phóng năng lực
Cách cấu hình thẻ meta và title động trong React với Helmet và với server Node.js

Nhiều người nhầm lẫn react-helmet là giải pháp để cải thiện Tối ưu hóa Công cụ Tìm kiếm (SEO) liên quan đến cấu hình thẻ meta. Thực tế không phải vậy. Trong bài viết này, chúng ta sẽ tìm hiểu cách thức react-helmet hoạt động và cách cập nhật động các thẻ meta (sử dụng máy chủ NodeJS) cho mục đích SEO.

 

Vị trí của react-helmet

react-helmet được sử dụng trong các ứng dụng React để cập nhật động các thẻ meta. Điều này đạt được với Javascript, do đó nó sẽ không hoạt động nếu Javascript không được hỗ trợ hoặc thực thi.

react-helmet được sử dụng trong các component kiểm soát các thẻ meta tại phiên bản cụ thể đó.

Một ứng dụng React tiêu chuẩn có một file index.html trong thư mục public trông giống như sau:

<html>
<head>
  <title>React App</title>
  <meta name="viewport" content="width=device-width, initial-scale=1" />
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
</body>
</html>

Đây là cấu hình thẻ head mà tất cả các trang (như được định cấu hình với react-router-dom hoặc bất kỳ gói định tuyến phía máy khách nào) sẽ có. Ý tôi là, các route '/ about' và '/ contact' sẽ có một thẻ title với nội dung là 'React App'.

Khi nào sử dụng

react-helmet giúp sửa đổi các thẻ head một cách dễ dàng. Điều này tốt hơn so với cách tiếp cận thủ công sử dụng JavaScript để thêm các phần tử vào thẻ head.

Cách sử dụng

Trước tiên, bạn cần cài đặt gói trong thư mục dự án của mình bằng lệnh này:

npm i --save react-helmet

Giả sử chúng ta muốn đặt các thẻ meta của một trang có tên là 'Contact us', chúng ta sẽ có như sau:

import React from 'react'
import Helmet from 'react-helmet';
-----
const Contact = () => {
    return (
        <>
            <Helmet>
                <title>Contact us</title>
                <meta name='description' content='Contact us if you have any question or requests'>
            </Helmet>
            <main>
                Contact Us
            </main>
        </>
    )
}
-----
export default Helmet

Lưu ý : <> là một thay thế cho React.Fragment. Sự khác biệt duy nhất đó là <> không phải là prop key mà chỉ là những prop fragment có thể có.

Với ví dụ trên, các thẻ meta sẽ được cập nhật bất cứ khi nào component này được sử dụng.

Sử dụng ở đâu

react-helmet có thể được sử dụng ở bất cứ đâu. Tại bất kỳ trường hợp nào của nó, các thẻ meta sẽ được cập nhật tương ứng. Ví dụ: nếu component Contact ở trên được sử dụng trong một component Nav chẳng hạn và Nav được sử dụng trong một component Home là một trang, thì title của trang đó sẽ là 'Contact us'.

Khi bạn sử dụng hai component react-helmet, thì component được khai báo cuối cùng sẽ được sử dụng. Hãy nhớ rằng component chỉ là JavaScript với các hàm được gợi lên. Vì vậy, điều này sẽ có ý nghĩa đối với bạn:

let a = 1 // thể hiện đầu tiên của react-helmet
a = 2 // thể hiện thứ hai
console.log(a)
// 2

react-helmet hoạt động rất nhanh, do đó khó nhận thấy, nhưng những gì xảy ra trong trình duyệt là:

  1. Yêu cầu một trang với đường dẫn của nó.
  2. Tìm nạp các tài nguyên cho trang đó.
  3. Tải HTML mặc định (với thẻ meta và title = 'React App').
  4. Thực thi các mã JavaScript mà các thẻ meta được cập nhật qua react-helmet.

Cách thức hoạt động của Helmet

react-helmet không phải là giải pháp hoàn hảo

Như tôi đã trình bày ở trên, react-helmet bao gồm các mã JavaScript được thực thi bởi trình duyệt. Điều này có nghĩa là nếu các chức năng đó không được kích hoạt, mọi trang sẽ vẫn có một title là 'React App'.

Với tất cả những điều đã nói, bây giờ bạn sẽ hiểu rằng khi bạn lưu trữ React app của mình trên bất kỳ máy chủ nào, các thẻ meta vẫn là mặc định. Nó chỉ thay đổi khi trình duyệt yêu cầu các tài nguyên trên một trang và chức năng react-helmet được sử dụng ở đó được thực thi.

Trình thu thập thông tin bot SEO không thực thi các chức năng JavaScript .

Cách thức hoạt động của trình thu thập thông tin bot SEO

Nếu bất kỳ trình thu thập thông tin nào thu thập thông tin qua một trang trên ứng dụng React của bạn, chúng sẽ lập chỉ mục trang đó bằng các thẻ meta mặc định (hiện tại title là 'React App'). Vì vậy, khách hàng của bạn nhìn thấy 'Contact' trên trình duyệt nhưng trình thu thập thông tin lại thấy 'React App'.

Như vậy bạn sẽ thấy rằng: react-helmet không phải là giải pháp để cải thiện SEO của các trang web

Bạn có thể không quan tâm đến SEO, nhưng một lý do khác khiến bạn cần đảm bảo các thẻ chính xác là ví dụ, các dịch vụ như tóm tắt trang twitter hiển thị hình ảnh, tiêu đề và mô tả được khai báo cho trang của bạn. Khi bạn tạo một tweet với một URL, twitter sẽ cố gắng xem trước URL đó. Điều này có nghĩa là, nó sẽ thực hiện một yêu cầu đến máy chủ đang nắm giữ các tài nguyên của trang đó. Twitter sẽ không giúp bạn chạy bất kỳ JavaScript nào, do đó, những gì sẽ được trả lại từ máy chủ sẽ là title 'React App'.

Lưu ý rằng trong một số framework React như GatsbyJS (mà tôi biết), react-helmet hoạt động với gatsby-plugin-react-helmet để sửa đổi các thẻ meta một cách thích hợp trong quá trình kết xuất phía máy chủ của chúng. Bên cạnh các framework như vậy, hãy nhớ rằng react-helmet không thể tự hoạt động cho đến khi các chức năng được trình duyệt thực thi.

Một giải pháp tốt hơn

Giải pháp là cấu hình động các thẻ meta từ máy chủ trước khi phản hồi lại máy khách (trình duyệt). Đây chỉ là một trong số các giải pháp khác (ví dụ như hydrat hóa) có sẵn.

Minh họa cấu hình động của thẻ meta từ máy chủ

Trong phần tiếp theo, chúng ta sẽ xem xét cách đạt được điều này.

Mục tiêu là, khi trình duyệt yêu cầu bất kỳ trang nào, máy chủ sẽ cập nhật các thẻ meta trước khi trả lời máy khách bằng các tài nguyên của trang. Bằng cách này, trình thu thập dữ liệu SEO hoặc các dịch vụ như xem trước trang twitter không phải chạy bất kỳ JavaScript nào. Họ chỉ nhận tài nguyên từ máy chủ.

Lưu ý rằng nếu bạn đang sử dụng component Link được cung cấp bởi react-router-dom, bạn vẫn cần react-helmet khi tự động cập nhật thẻ meta từ máy chủ. Điều này là do React là một Ứng dụng Trang Đơn (SPA). Tất cả các tài nguyên sẽ được sử dụng bởi trang web đều được tìm nạp trước. Với component Link, việc nhấp vào liên kết từ trang chủ (ví dụ) sẽ không yêu cầu từ máy chủ nữa. Thay vào đó, các tài nguyên được tìm nạp trước cho trang đó sẽ được sử dụng. Đây là lý do tại sao component Link điều hướng nhanh hơn.

Với hành vi này, khi bạn yêu cầu trang chỉ mục của ứng dụng React của mình, máy chủ sẽ tự động thay đổi thẻ tiêu đề thành 'Homepage' (như bạn đã định cấu hình) nhưng điều hướng đến các trang khác bằng component Link sẽ khiến các trang khác cũng có tiêu đề 'Homepage' . Hãy nhớ rằng Link không thực hiện bất kỳ yêu cầu nào đối với máy chủ, do đó, chúng sẽ không có thẻ meta thích hợp cho các trang khác. Ngoại trừ bằng cách làm mới trang.

Do đó, react-helmet có lợi ở phía trình khách khi Link được sử dụng. Ngoài ra, bạn có thể sử dụng a (thẻ liên kết) cho các liên kết đảm bảo rằng mọi điều hướng sẽ luôn yêu cầu tài nguyên từ máy chủ.

Cách định cấu hình thẻ meta từ máy chủ

Chúng ta sẽ sử dụng NodeJS để phục vụ các tài nguyên của ứng dụng của chúng ta. NodeJS cũng sẽ chịu trách nhiệm cập nhật các thẻ meta trước khi phản hồi.

React app của bạn có thể được lưu trữ trên máy chủ heroku hoặc bất kỳ nơi nào, nhưng nguyên tắc tương tự cũng được áp dụng.

Hãy xem ví dụ cơ bản này, đây là tập tin máy chủ server.js:

const path = require('path');
const express = require("express");
const app = express();
-----
app.use(express.static(path.join(__dirname, "build")));
app.get("*", (req, res) =>
 res.sendFile(path.join(__dirname, "build/index.html"))
);
-----
const port = process.env.PORT || 5000;
app.listen(port, () => {
 console.log(`Server started on port ${port}`);
})

Trong ví dụ trên:

  • express.static được sử dụng để cung cấp các file tĩnh trong ứng dụng React.
  • thư mục build là store cho các tập tin tĩnh (để được phục vụ) được xây dựng với npm run build.
  • app.get('*') đáp ứng tất cả các yêu cầu nhận được với tệp index.html trong thư mục build.

Với những điều này, các thẻ mặc định sẽ được trả về trong phản hồi cho mọi trang. Để định cấu hình các thẻ meta của mỗi trang, chúng ta cần chú ý đến chúng theo cách khác nhau.

Một cách dễ dàng để thực hiện việc này là đặt một chuỗi mẫu vào tệp public/index.html (kết quả là build/index.html). Sau đó, chúng ta sẽ nhắm mục tiêu chuỗi đó và thay thế nó tương ứng với trang được yêu cầu.

Ví dụ:

<html>
<head>
  __PAGE_META__
  <meta name="viewport" content="width=device-width, initial-scale=1" />
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
</body>
</html>

Tiếp theo, chúng ta sẽ đọc tệp index.html, thay thế __PAGE META \ _ bằng các thẻ meta mà chúng ta muốn và gửi nội dung cập nhật.

Trong tệp server.js, chúng tôi sẽ thêm những điều sau:

const path = require("path")
const express = require("express")
const app = express()
const fs = require("fs")
//
const pathToIndex = path.join(__dirname, "build/index.html")
app.get("/", (req, res) => {  const raw = fs.readFileSync(pathToIndex)
const pageTitle = "Homepage - Welcome to my page"
const updated = raw.replace("__PAGE_META__", `<title>${pageTitle}</title>`)
res.send(updated)})
//
app.use(express.static(path.join(__dirname, "build")))
app.get("*", (req, res) =>
  res.sendFile(path.join(__dirname, "build/index.html"))
)
const port = process.env.PORT || 5000
app.listen(port, () => {
  console.log(`Server started on port ${port}`)
})

fs nhận nội dung của index.html một cách đồng bộ, thay thế chuỗi mẫu bằng meta mong muốn của chúng ta và gửi phiên bản cập nhật dưới dạng phản hồi. Bạn có thể làm tương tự đối với các thẻ meta khác như '<meta name =' description 'content = ${pageDescription}>', v.v.

Vì mã được chạy bởi máy chủ của bạn, bạn cũng có thể nhận được các giá trị động. Ví dụ: một sản phẩm hoặc người dùng mà bạn sử dụng /:id để lấy thông tin chi tiết. Bạn có thể thực hiện các thao tác cần thiết để lấy thông tin chi tiết của nó trước khi thay thế tệp index.html và gửi trở lại trình duyệt.

Bằng cách này, bạn chắc chắn rằng những gì mà trình thu thập thông tin, trình duyệt hoặc dịch vụ twitter nhận được trong cấu hình thẻ meta chính xác này.

Lưu ý đi kèm với cách tiếp cận này là bạn cần phải xử lý mọi đường dẫn trên ứng dụng React của mình.

Phần kết luận

react-helmet là một công cụ tuyệt vời, nhưng lợi ích của nó chỉ xuất hiện ở phía trình khách. Chúng ta cần máy chủ của mình để định cấu hình các thẻ meta trước khi trả lời bất kỳ ứng dụng khách nào, vì ứng dụng khách đó có thể không chạy được JavaScript trong react-helmet.

Khi sử dụng component Link, hãy nhớ sử dụng react-helmet vì Link sẽ không thực hiện bất kỳ yêu cầu nào đối với máy chủ khi điều hướng.

» Tiếp: Cách thiết lập nội dung động cho title và meta với react-meta-tags
« Trước: Cách thiết lập Adsense trên app React
Các khóa học qua video:
Python SQL Server PHP C# Lập trình C Java HTML5-CSS3-JavaScript
Học trên YouTube <76K/tháng. Đăng ký Hội viên
Viết nhanh hơn - Học tốt hơn
Giải phóng thời gian, khai phóng năng lực
Copied !!!