---
# System prepended metadata

title: Nuxt3 社群分享功能
tags: [已重新整理]

---

# 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)