# Nuxt3 社群分享功能
如何在 Nuxt3 中使用官方提供的 Web API 實作社群媒體分享功能。
---
## 功能特色
✅ 支援多個社群平台:
- Facebook
- WhatsApp
- LINE (桌面版/行動版)
- Email
- X (Twitter)
- 微博 (Weibo)
✅ 無需第三方套件
✅ 使用官方分享 API
✅ 支援 RWD (LINE 自動判斷裝置)
---
## 完整實作
### Template
```vue
<template>
<div class="share-container">
<h3>分享到</h3>
<ul class="share-list">
<!-- Facebook -->
<li>
<a :href="shareFB" target="_blank" rel="noopener noreferrer">
<img src="@/assets/img/icon_fb_logo.svg" alt="分享到 Facebook">
</a>
</li>
<!-- WhatsApp -->
<li>
<a :href="shareWhatsapp" target="_blank" rel="noopener noreferrer">
<img src="@/assets/img/icon_whatsapp_logo.svg" alt="分享到 WhatsApp">
</a>
</li>
<!-- LINE -->
<li>
<button @click="shareLine" type="button">
<img src="@/assets/img/icon_line_logo.svg" alt="分享到 LINE">
</button>
</li>
<!-- X (Twitter) -->
<li>
<a :href="shareX" target="_blank" rel="noopener noreferrer">
<img src="@/assets/img/icon_x_logo.svg" alt="分享到 X">
</a>
</li>
<!-- 微博 -->
<li>
<a :href="shareWeibo" target="_blank" rel="noopener noreferrer">
<img src="@/assets/img/icon_weibo_logo.svg" alt="分享到微博">
</a>
</li>
<!-- Email -->
<li>
<a :href="shareEmail">
<img src="@/assets/img/icon_email.svg" alt="Email 分享">
</a>
</li>
</ul>
</div>
</template>
```
---
### Script Setup
```vue
<script setup>
// ===========================
// 分享設定
// ===========================
// 分享文字內容
const shareText = '來看看這個精彩內容!'
const shareTitle = '文章標題'
// 分享連結
const shareFB = ref('')
const shareWhatsapp = ref('')
const shareLine = ref('')
const shareX = ref('')
const shareWeibo = ref('')
const shareEmail = ref('')
/**
* 取得當前頁面網址
* @returns {string} 當前完整 URL
*/
const getCurrentUrl = () => {
if (process.client) {
return window.location.href
}
return ''
}
/**
* LINE 分享
* 桌面版: 開啟 LINE 分享視窗
* 行動版: 開啟 LINE App
*/
const handleShareLine = () => {
if (!process.client) return
const url = encodeURIComponent(getCurrentUrl())
// 判斷是否為桌面版 (寬度 > 960px)
if (window.innerWidth > 960) {
// 桌面版: 開啟 LINE 社群外掛
window.open(`https://social-plugins.line.me/lineit/share?url=${url}`)
} else {
// 行動版: 開啟 LINE App
const message = encodeURIComponent(`${shareText}\n${getCurrentUrl()}`)
window.location.href = `line://msg/text/${message}`
}
}
/**
* 初始化所有分享連結
*/
const initializeShareLinks = () => {
if (!process.client) return
const currentUrl = getCurrentUrl()
const encodedUrl = encodeURIComponent(currentUrl)
const encodedText = encodeURIComponent(shareText)
const encodedTitle = encodeURIComponent(shareTitle)
// Facebook 分享
shareFB.value = `https://www.facebook.com/sharer/sharer.php?u=${encodedUrl}`
// WhatsApp 分享
shareWhatsapp.value = `https://api.whatsapp.com/send?text=${encodedText}:${encodedUrl}`
// X (Twitter) 分享
shareX.value = `https://twitter.com/intent/tweet?text=${encodedText}&url=${encodedUrl}`
// 微博分享
shareWeibo.value = `http://service.weibo.com/share/share.php?url=${encodedUrl}&title=${encodedText}`
// Email 分享
const emailSubject = encodeURIComponent('推薦給你')
const emailBody = encodeURIComponent(`${shareText}\n${shareTitle}\n${currentUrl}`)
shareEmail.value = `mailto:?subject=${emailSubject}&body=${emailBody}`
}
// 頁面載入時初始化分享連結
onMounted(() => {
initializeShareLinks()
})
</script>
```
---
### Style (SCSS)
```vue
<style lang="scss" scoped>
.share-container {
padding: 1.5rem;
h3 {
margin-bottom: 1rem;
font-size: 1.125rem;
font-weight: 600;
}
}
.share-list {
display: flex;
gap: 1rem;
list-style: none;
padding: 0;
margin: 0;
flex-wrap: wrap;
li {
a,
button {
display: inline-flex;
align-items: center;
justify-content: center;
width: 48px;
height: 48px;
padding: 0;
background: transparent;
border: none;
cursor: pointer;
transition: transform 0.2s ease;
&:hover {
transform: scale(1.1);
}
&:active {
transform: scale(0.95);
}
img {
width: 100%;
height: 100%;
object-fit: contain;
}
}
}
}
// 響應式設計
@media (max-width: 768px) {
.share-list {
gap: 0.75rem;
li a,
li button {
width: 40px;
height: 40px;
}
}
}
</style>
```
---
## 各平台分享 API 說明
### 1. Facebook
```javascript
// 基本格式
https://www.facebook.com/sharer/sharer.php?u={URL}
// 範例
shareFB.value = `https://www.facebook.com/sharer/sharer.php?u=${encodeURIComponent(url)}`
```
**注意事項:**
- ⚠️ 在 localhost 無法正常運作 (Facebook 審核機制)
- 需要在測試機或正式機測試
- 分享的標題、圖片、描述由 Open Graph 標籤決定
- 如果顯示舊內容,請使用 [Facebook 分享偵錯工具](https://developers.facebook.com/tools/debug/)清除快取
---
### 2. WhatsApp
```javascript
// 基本格式
https://api.whatsapp.com/send?text={文字}
// 範例
const text = encodeURIComponent('來看看這個!')
const url = encodeURIComponent(window.location.href)
shareWhatsapp.value = `https://api.whatsapp.com/send?text=${text}:${url}`
```
**特性:**
- 桌面版和行動版使用相同 URL
- 會自動開啟 WhatsApp 網頁版或 App
---
### 3. LINE
LINE 需要根據裝置類型使用不同的 URL:
```javascript
const shareLine = () => {
if (!process.client) return
const url = getCurrentUrl()
if (window.innerWidth > 960) {
// 桌面版: LINE 社群外掛
window.open(`https://social-plugins.line.me/lineit/share?url=${encodeURIComponent(url)}`)
} else {
// 行動版: LINE App URL Scheme
const message = encodeURIComponent(`${text}\n${url}`)
window.location.href = `line://msg/text/${message}`
}
}
```
**URL Scheme 說明:**
- 桌面版: `https://social-plugins.line.me/lineit/share?url={URL}`
- 行動版: `line://msg/text/{訊息}`
---
### 4. X (Twitter)
```javascript
// 基本格式
https://twitter.com/intent/tweet?text={文字}&url={URL}
// 範例
const text = encodeURIComponent('來看看這個!')
const url = encodeURIComponent(window.location.href)
shareX.value = `https://twitter.com/intent/tweet?text=${text}&url=${url}`
```
**可用參數:**
- `text`: 推文內容
- `url`: 分享網址
- `hashtags`: 標籤 (逗號分隔)
- `via`: 提及的使用者
---
### 5. 微博 (Weibo)
```javascript
// 基本格式
http://service.weibo.com/share/share.php?url={URL}&title={標題}
// 範例
const url = encodeURIComponent(window.location.href)
const title = encodeURIComponent('文章標題')
shareWeibo.value = `http://service.weibo.com/share/share.php?url=${url}&title=${title}`
```
---
### 6. Email
```javascript
// 基本格式
mailto:?subject={主旨}&body={內容}
// 範例
const subject = encodeURIComponent('推薦給你')
const body = encodeURIComponent(`來看這篇文章\n${url}`)
shareEmail.value = `mailto:?subject=${subject}&body=${body}`
```
**注意:**
- 換行使用 `\n`
- 需要 URL encode
- 會開啟使用者預設的郵件客戶端
---
## 進階功能
### 1. 使用 Composable 封裝
建立 `composables/useSocialShare.js`:
```javascript
export const useSocialShare = () => {
/**
* 取得當前頁面 URL
*/
const getCurrentUrl = () => {
if (!process.client) return ''
return window.location.href
}
/**
* 產生 Facebook 分享連結
*/
const getFacebookShareUrl = (url = getCurrentUrl()) => {
return `https://www.facebook.com/sharer/sharer.php?u=${encodeURIComponent(url)}`
}
/**
* 產生 WhatsApp 分享連結
*/
const getWhatsAppShareUrl = (text, url = getCurrentUrl()) => {
const encodedText = encodeURIComponent(text)
const encodedUrl = encodeURIComponent(url)
return `https://api.whatsapp.com/send?text=${encodedText}:${encodedUrl}`
}
/**
* 產生 X (Twitter) 分享連結
*/
const getXShareUrl = (text, url = getCurrentUrl(), hashtags = '') => {
const encodedText = encodeURIComponent(text)
const encodedUrl = encodeURIComponent(url)
let shareUrl = `https://twitter.com/intent/tweet?text=${encodedText}&url=${encodedUrl}`
if (hashtags) {
shareUrl += `&hashtags=${encodeURIComponent(hashtags)}`
}
return shareUrl
}
/**
* 產生微博分享連結
*/
const getWeiboShareUrl = (title, url = getCurrentUrl()) => {
const encodedTitle = encodeURIComponent(title)
const encodedUrl = encodeURIComponent(url)
return `http://service.weibo.com/share/share.php?url=${encodedUrl}&title=${encodedTitle}`
}
/**
* 產生 Email 分享連結
*/
const getEmailShareUrl = (subject, body) => {
const encodedSubject = encodeURIComponent(subject)
const encodedBody = encodeURIComponent(body)
return `mailto:?subject=${encodedSubject}&body=${encodedBody}`
}
/**
* LINE 分享
*/
const shareLine = (text, url = getCurrentUrl()) => {
if (!process.client) return
const encodedUrl = encodeURIComponent(url)
if (window.innerWidth > 960) {
// 桌面版
window.open(`https://social-plugins.line.me/lineit/share?url=${encodedUrl}`)
} else {
// 行動版
const message = encodeURIComponent(`${text}\n${url}`)
window.location.href = `line://msg/text/${message}`
}
}
return {
getCurrentUrl,
getFacebookShareUrl,
getWhatsAppShareUrl,
getXShareUrl,
getWeiboShareUrl,
getEmailShareUrl,
shareLine
}
}
```
**使用範例:**
```vue
<script setup>
const {
getFacebookShareUrl,
getWhatsAppShareUrl,
shareLine
} = useSocialShare()
const shareText = '來看看這個精彩內容!'
const shareFB = computed(() => getFacebookShareUrl())
const shareWhatsapp = computed(() => getWhatsAppShareUrl(shareText))
</script>
```
---
### 2. 支援動態內容分享
```vue
<script setup>
// 假設從 API 取得文章資料
const { data: article } = await useFetch('/api/article/123')
// 動態產生分享內容
const shareText = computed(() => {
return article.value?.title || '精彩內容'
})
const shareUrl = computed(() => {
if (!process.client) return ''
return window.location.href
})
// 使用動態內容
const shareFB = computed(() => {
return `https://www.facebook.com/sharer/sharer.php?u=${encodeURIComponent(shareUrl.value)}`
})
const shareWhatsapp = computed(() => {
const text = encodeURIComponent(shareText.value)
const url = encodeURIComponent(shareUrl.value)
return `https://api.whatsapp.com/send?text=${text}:${url}`
})
</script>
```
---
### 3. 加入分享追蹤 (UTM 參數)
```javascript
const getShareUrlWithTracking = (baseUrl, platform) => {
const url = new URL(baseUrl)
url.searchParams.set('utm_source', platform)
url.searchParams.set('utm_medium', 'social')
url.searchParams.set('utm_campaign', 'share')
return url.toString()
}
// 使用範例
const currentUrl = getCurrentUrl()
const facebookUrl = getShareUrlWithTracking(currentUrl, 'facebook')
shareFB.value = `https://www.facebook.com/sharer/sharer.php?u=${encodeURIComponent(facebookUrl)}`
```
---
### 4. Web Share API (原生分享)
現代瀏覽器支援原生分享功能:
```vue
<script setup>
const canShare = ref(false)
onMounted(() => {
// 檢查是否支援 Web Share API
canShare.value = process.client && navigator.share !== undefined
})
const handleNativeShare = async () => {
if (!canShare.value) return
try {
await navigator.share({
title: '文章標題',
text: '來看看這個精彩內容!',
url: window.location.href
})
console.log('分享成功')
} catch (error) {
if (error.name !== 'AbortError') {
console.error('分享失敗:', error)
}
}
}
</script>
<template>
<!-- 顯示原生分享按鈕 -->
<button v-if="canShare" @click="handleNativeShare">
<img src="@/assets/img/icon_share.svg" alt="分享">
</button>
<!-- 其他平台分享按鈕 -->
<ul v-else class="share-list">
<!-- ... -->
</ul>
</template>
```
**Web Share API 特性:**
- ✅ 自動顯示裝置上可用的分享選項
- ✅ 更好的使用者體驗
- ⚠️ 僅在 HTTPS 環境下可用
- ⚠️ 必須由使用者互動觸發 (如按鈕點擊)
---
## 常見問題
### Q: Facebook 分享在本地環境無法運作?
A: Facebook 不允許分享 localhost 的網址,需要部署到測試機或正式機才能測試。
---
### Q: Facebook 分享顯示的標題/圖片不正確?
A:
1. 確認網頁有正確設定 Open Graph 標籤
2. 使用 [Facebook 分享偵錯工具](https://developers.facebook.com/tools/debug/)清除快取
3. 強制重新抓取內容
```html
<!-- 必要的 OG 標籤 -->
<meta property="og:title" content="頁面標題">
<meta property="og:description" content="頁面描述">
<meta property="og:image" content="https://example.com/image.jpg">
<meta property="og:url" content="https://example.com/page">
```
---
### Q: LINE 分享在桌面版無法開啟?
A: 確認使用正確的 URL:
- 桌面版: `https://social-plugins.line.me/lineit/share?url={URL}`
- 行動版: `line://msg/text/{訊息}`
---
### Q: 如何判斷使用者使用的裝置?
A: 可以使用 `window.innerWidth` 或 User Agent:
```javascript
// 方法一: 螢幕寬度
const isMobile = window.innerWidth <= 960
// 方法二: User Agent
const isMobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(
navigator.userAgent
)
```
---
### Q: 分享連結中的特殊字元如何處理?
A: 使用 `encodeURIComponent()` 編碼:
```javascript
const url = 'https://example.com/article?id=123&lang=zh'
const encodedUrl = encodeURIComponent(url)
// 輸出: https%3A%2F%2Fexample.com%2Farticle%3Fid%3D123%26lang%3Dzh
```
---
## 瀏覽器相容性
| 功能 | Chrome | Firefox | Safari | Edge |
|------|--------|---------|--------|------|
| 基本分享連結 | ✅ | ✅ | ✅ | ✅ |
| Web Share API | ✅ 89+ | ✅ 71+ | ✅ 12.2+ | ✅ 93+ |
| LINE URL Scheme | ✅ | ✅ | ✅ | ✅ |
---
## 參考資源
- [Facebook 分享偵錯工具](https://developers.facebook.com/tools/debug/)
- [Open Graph Protocol](https://ogp.me/)
- [Web Share API - MDN](https://developer.mozilla.org/en-US/docs/Web/API/Navigator/share)
- [LINE Developers](https://developers.line.biz/)
- [Twitter Web Intent](https://developer.twitter.com/en/docs/twitter-for-websites/tweet-button/overview)