Hôm nay mình sẽ hướng dẫn các bạn cách share ảnh thumbnail, title, description động lên facebook trong ứng dụng ReactJS như dưới đây
URL: https://ymeet.me/
Có vẻ như một hướng dẫn tương tự đã có rất nhiều trên internet, các bạn có thể tìm trong vòng 1 nốt nhạc :). Điểm khác biệt ở đây là:
- Sau khi build trên production, ứng dụng ReactJS chỉ còn là static files (html, css, js)
- Làm sao để hiển thị thumbnail động theo article
Ở bài viết này mình sử dụng NginX để làm web server, bình thường sau khi deploy lên production. Nginx sẽ config như sau:
server { listen 80; server_name domain.com; location / { add_header Access-Control-Allow-Origin *; add_header Access-Control-Allow-Methods "POST, GET, OPTIONS"; add_header Access-Control-Allow-Headers "Origin, Authorization, Accept"; add_header Access-Control-Allow-Credentials true; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-FORWARDED_PROTO $scheme; proxy_set_header Host $http_host; root /var/www/web; index index.html; try_files $uri $uri/ /index.html; #proxy_redirect off; #proxy_pass http://localhost:8088; } }
Để Facebook có thể hiển thị thumbnail, title, description blah blah của bài viết lên facebook, ở thẻ <header> file index.html chúng ta cần có
<html class="no-js" lang="vi"> <head> <meta property="og:image:width" content="600" /> <meta property="og:image:height" content="315" /> <meta property="og:description" content="Click xem ngay" /> <meta property="og:site_name" content="ymeet.me" /> <meta id="og-image" property="og:image" content="https://odpublic-s3-amazonaws.cdn.vccloud.vn/general/MiniGame/QuizVui/Answer/Huong_Tram.png" /> <meta property="og:image" content="Người yêu bạn là ai trong Em gái mưa?" /> <title>Người yêu bạn là ai trong Em gái mưa?</title> </head> </html>
Câu hỏi đặt ra, do website chỉ là static file, làm thế nào mình co thể hiển thị động đc các nội dung title, description, thumbnail. Ở đây mình sẽ sử dụng nodejs để render index.html từ phía server. Các nội dung title, description, thumbnail sẽ được truyền trực tiếp trên url như sau
- File routers trong ReactJS
export default ( <Route path="/" component={App}> <Route path="/similar-sharing/:current_user_id/:mode/:id(/:similar_img)" component={SimilarSharing} /> {/* It should be the last route item */} <Route path="/404" component={FileNotFound} /> <Redirect from="*" to="/404" /> </Route> )
- Tạo 1 file với tên sharing.html trong thư mục web root với nội dung tương tự file index.html
<!doctype html> <html class="no-js" lang="vi"> <head> <meta charset="utf-8"> <meta property="og:image:width" content="600" /> <meta property="og:image:height" content="315" /> <meta property="og:description" content="Click xem ngay" /> <meta property="og:site_name" content="ymeet.me" /> <meta id="og-image" property="og:image" content="__sharing_img_url__" /> <meta property="og:title" content="__title__" /> <title>__title__</title> <link rel="stylesheet" type="text/css" href="/css/style.css" /> </head> <body> <div id="root" style="min-height: 100vh"></div> <script src="/js/bundle.js"></script> </body> </html>
- Tạo nodejs
var express = require('express'); fs = require('fs'); var path = require('path'); var app = express(); var port = 8088; //app.use(express.static('js')); app.use("/js", express.static(__dirname + '/js')); app.use("/css", express.static(__dirname + '/css')); app.use("/scripts", express.static(__dirname + '/scripts')); app.use("/manifest", express.static(__dirname + '/manifest')); app.use(function(req, res, next) { res.header("Access-Control-Allow-Origin", "*"); res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept"); res.header("X-Frame-Options", "SAMEORIGIN"); res.header("X-XSS-Protection", "1"); res.header("X-Content-Type-Options", "nosniff"); next(); }); // the following for similar sharing page only app.get('/similar-sharing/:current_user_id/:mode/:id/:similar_img', function(req, res) { fs.readFile('sharing.html', 'utf8', function (err,data) { if (err) { return console.log(err); } res.send(data.replace('__sharing_img_url__', 'https://ymmuploads-s3-amazonaws.cdn.vccloud.vn/combineimage/' + req.params.similar_img)) }); // res.sendFile(path.join(__dirname, 'sharing.html')); }); app.get('*', function(req, res) { res.sendFile(path.join(__dirname, 'index.html')); }); var server = app.listen(port, '0.0.0.0', function(err) { if (err) { console.log(err); return; } console.log('Listening at http://0.0.0.0:' + port); })
- Config trong Nginx
location ~/similar-sharing/(\d+)/(\d+)/(\d+)/(.*) { proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-FORWARDED_PROTO $scheme; proxy_set_header Host $http_host; proxy_redirect off; proxy_pass http://localhost:8088; }