Facebook Sharing กับ SPA อย่าง Angular
เกริ่นนิด ๆ กับที่มาของบทความนี้ มีงานนึงจากลูกค้าที่มีการแชร์ไปยัง Social Media ต่าง ๆ เช่น Facebook หรือ Twitter แต่เมื่อทดลองแชร์ลิงค์เข้าจริง ๆ กับ Angular มันกลับไม่เป็นอย่างที่คิด จึงเกิดเป็นบทความแรกนี้ขึ้นมา กราบฝากเนื้อฝากตัวด้วยครับ 🙏🏻
เนื่องจากตัว Angular เองเป็น SPA หรือ Single Page Application ทำให้ ถ้าดู Source Code ก็จะเห็นเพียงเนื้อหาที่มาจากไฟล์ index.html ซึ่งดูไม่ค่อยเป็นมิตรต่อ SEO (Search Engine Optimization) สักเท่าไหร่นัก เพราะ Preview ตอนแชร์มันไม่ค่อยสวยซักเท่าไร
ถึงแม้เราจะสามารถแก้ไข Meta Tag จาก ไฟล์ index.html
ได้ แต่มันก็เป็นแบบ Static ซึ่งสำหรับ SPA นั้น จะต้อง Render ก่อนจึงจะเห็นความเปลี่ยนแปลงจากไฟล์ index.html
นี้
แต่วิธีนี้ก็ไม่ใช่วิธีแก้ปัญหาที่ตรงจุดอยู่ดี
วิธีรับมือกับ Crawler จาก Facebook
- Pre-rendering
- Angular Universal
- Facebook SDK
Pre-rendering และ Angular Universal
หลักการคร่าว ๆ ของ 2 วิธีแรกจะใช้หลักการเดียวกันคือ เว็บเซิฟเวอร์จะแยก Request ว่ามาจาก Browser หรือจากบอท (Crawler) ที่มาจาก Social Media
โดยถ้ามาจาก Browser ก็จะให้เข้าใช้งานได้ปกติ แต่ถ้าเป็นบอทจะบอก Angular เพื่อเปลี่ยนไปไป Render บน Headless Browser แล้วส่ง HTML Snapshot ให้กับบอทแทน
แต่ด้วยเว็บเซิฟเวอร์นั้นเป็นของลูกค้า และค่อนข้างจะ Legacy อยู่พอสมควร วิธีนี้จึงตกไป (ถ้าเว็บเซิฟเวอร์ที่คุณดูแลอยู่สามารถใช้วิธีนี้ได้ ก็ยินดีด้วย)
Facebook SDK
ในบทความนี้จะมาพูดถึงการนำ Facebook SDK มาแก้ปัญหาการแชร์นี้กัน ซึ่งกับเจ้า Angular นั้นมีตัวช่วยอย่าง ngx-facebook ให้ใช้งานร่วมกับ TypeScript ได้ง่ายขึ้น
เริ่มจากติดตั้ง Package ของ ngx-facebook ก่อนเลย
npm i --save ngx-facebook
จากนั้นนำคำสั่ง
<script type="text/javascript" src="https://connect.facebook.net/en_US/sdk.js"></script>
ไปใส่ไว้ใน index.html
แล้วทำการ Import FacebookModule ก็เป็นอันเริ่มต้นใช้งานได้
import { FacebookModule } from 'ngx-facebook';@NgModule({
...
imports: [
FacebookModule.forRoot()
],
...
})
export class AppModule { }
และอีกอย่างนึงคือ จำเป็นต้องมี App ใน Facebook Developer และเพิ่ม URL ของ Site เราไปใน Platform ของ Website (สำหรับ Mobile จะใช้อีกวิธีนึง)
เมื่อเราได้ App ID มาแล้ว เราก็สามารถใช้งาน Function init ได้แล้ว ดังข้างล่างเลย
constructor(private fb: FacebookService) {
const initParams: InitParams = {
appId: '<app-id>',
version: 'v3.0'
};
fb.init(initParams);
}
ขอคั่นนิดนึง เพราะตัว Facebook Develop ก็มี API สำหรับการแชร์ที่แสนจะง่ายดังนี้
ตะ..แต่ว่า มันดัน Deprecated ไปแล้ว 😭
มาถึงพระเอกของเราที่จะมาแก้ปัญหาเฉพาะหน้านี้กัน ก็คือ Open Graph Actions
FB.ui({
method: 'share_open_graph',
action_type: 'og.likes',
action_properties: JSON.stringify({
object:'https://developers.facebook.com/docs/',
})
}, function(response){});
ซึ่งด้วย Open Graph Actions นี้ จะมี action_type: 'og.shares'
ที่ทำงานได้ใกล้เคียงกับ API สร้าง Article เลย ซึ่ง action_properties
ก็สามารถ Custom แชร์โพสได้ตามสะดวกดังนี้ URL, Title, Description และ Image เป็นต้น
เท่านี้การแชร์ของเราก็สามารถ Custom ได้ตามที่ต้องการจะแชร์ ณ ขณะนั้นได้เลย 🎉
สำหรับในนามผู้พัฒนาเว็บแล้ววิธีการแชร์ด้วย Facebook SDK นี้ มันยังไม่ใช่วิธีการแก้ปัญหาที่ถูกต้องนัก ถ้าเทียบกับ Pre-rendering แต่ในเมื่อเราแก้ที่ต้นเหตุไม่ได้ ของแบบนี้รู้ไว้ใช่เสียหายครับ 😊