ReactJS: Cách thiết lập nội dung động cho title và meta với react-meta-tags
Xử lý thẻ <title> và thẻ <meta> trong React là một việc khó. Có một số mô-đun khác cũng trợ giúp điều này như react-helmet và react-document-meta, nhưng chúng yêu cầu định nghĩa các thẻ <title> và <meta> trong một đối tượng cụ thẻ. react-meta-tags cho phép bạn viết các thẻ đó theo cách khai báo và ở định dạng jsx bình thường.
Cài đặt
npm install react-meta-tags --save
Hoặc tải phiên bản development và production đã biên dịch từ ./dist
Sử dụng
Sử dụng component MetaTag
import React from 'react'; import MetaTags from 'react-meta-tags'; class Component1 extends React.Component { render() { return ( <div className="wrapper"> <MetaTags> <title>Page 1</title> <meta name="description" content="Some description." /> <meta property="og:title" content="MyApp" /> <meta property="og:image" content="path/to/image.jpg" /> </MetaTags> <div className="content"> Some Content </div> </div> ) } }
Lưu ý: Xác định id trên các thẻ để nếu bạn điều hướng đến trang khác, các thẻ meta cũ hơn sẽ bị xóa và thay thế bằng các thẻ mới.
Sử dụng component ReactTitle
Nếu bạn chỉ muốn thêm tiêu đề trên một trang, bạn có thể sử dụng ReactTitle để thay thế.
import React from 'react'; import {ReactTitle} from 'react-meta-tags'; class Component2 extends React.Component { render() { return ( <div className="wrapper"> <ReactTitle title="Page 2"/> <div className="content"> Some Content </div> </div> ) } }
Ví dụ về sử dụng máy chủ
import MetaTagsServer from 'react-meta-tags/server'; import {MetaTagsContext} from 'react-meta-tags'; /** Import những module khác nếu muốn ở đây **/ /* ------ một số code ở đây nếu có ------ */ app.use((req, res) => { //make sure you get a new metatags instance for each request const metaTagsInstance = MetaTagsServer(); //react router match match({ routes, location: req.url }, (error, redirectLocation, renderProps) => { let reactString; try{ reactString = ReactDomServer.renderToString( <Provider store={store}> {/*** If you are using redux ***/} {/* Bạn phải truyền extract thông qua MetaTagsContext để nó có thể bắt các thẻ meta */} <MetaTagsContext extract = {metaTagsInstance.extract}> <RouterContext {...renderProps}/> </MetaTagsContext> </Provider> ); } catch(e){ res.status(500).send(e.stack); return; } //gộp lại thành một chuỗi const meta = metaTagsInstance.renderToString(); //nạp chuỗi metatag tới layout const htmlStr = (` <!doctype html> <html lang="en-us"> <head> <meta charSet="utf-8"/> ${meta} </head> <body> <div id="content"> ${reactString} </div> </body> </html> `); res.status(200).send(layout); }); });
Như vậy, theo đoạn mã trên, chúng ta phải làm như sau để hiển thị title và meta ở máy chủ:
- Import MetaTagsServer và MetaTagsContext
- Tạo một phiên bản mới của MetaTagsServer
- Gộp component của bạn bên trong MetaTagsContext và extract như là các prop
- Trích xuất chuỗi meta bằng cách sử dụng renderToString của phiên bản MetaTagsServer
- Nối chuỗi meta vào mẫu html của bạn.
Bố cục JSX
Bạn cũng có thể sử dụng React để xác định bố cục của mình, trong trường hợp đó, bạn có thể sử dụng phương thức getTags
từ metaTagsInstance
. Phần bố cục của ví dụ phía trên máy chủ sẽ trông như thế này.
//gộp các title và meta thành các phần tử React const metaTags = metaTagsInstance.getTags(); //nạp chuỗi metatag tới layout const layout = ( <html lang="en-us"> <head> <meta charSet="utf-8"/> {metaTags} </head> <body> <div id="app" dangerouslySetInnerHTML={{__html: reactString}} /> </body> </html> ); const htmlStr = ReactDomServer.renderToString(layout); res.status(200).send(htmlStr);
Tính duy nhất của thẻ meta
- Mô-đun xác định duy nhất thẻ meta theo thuộc tính id/property/name/itemProp.
- Nhiều thẻ meta có cùng thuộc tính / tên hợp lệ trong html. Nếu bạn cần trường hợp như vậy. Xác định một id khác cho cả hai để có thể phân biệt tính duy nhất.
- Bạn nên cung cấp một id để nếu khóa meta là khác thì property/name/itemProp sẽ xác định duy nhất chúng.