---
# System prepended metadata

title: "\U0001F3C5 Day 11 - Global head Settings\_與 useHead"
tags: [2024 Nuxt 直播班]

---

# 🏅 Day 11 - Global head Settings 與 useHead

## 今日學習目標

- 在 **nuxt.config.ts** 設定全域的 SEO 設定
- 使用  useHead 組合函式設定單一頁面的SEO 設定

## 全域 head 設定 (Global head Settings)

Global head Settings 是用來設定網站所有頁面共用的 `<head>` 資訊，確保所頁面的 SEO 設定一致，並避免在各頁面重複寫相同的  `<head>` 資訊。

### 撰寫 Global head 的語法

可以在 `nuxt.config.ts` 中的 `app.head` 屬性內以**物件**的方式定義全部頁面的 head 資訊。

```jsx
// nuxt.config.ts
export default defineNuxtConfig({
  app: {
    head: {
     // 在 head 物件內定義  head 資訊
    },
  },
});

```

head 資訊是基於 [Unhead](https://unhead.harlanzw.com/)  套件的格式進行撰寫。因為 Nuxt3 整合了 [Unhead](https://unhead.harlanzw.com/) 套件，所以就可以更方便地控制各頁面的 `<head>` 資訊，定義 SEO 相關的 meta tags、外部資源的載入、樣式設定等。接下來將使用範例的方式針對經常使用的屬性進行解說，更多的屬性可以至  [Unhead 官方文件](https://unhead.harlanzw.com/) 閱讀 。

 

### 範例

```jsx
// nuxt.config.ts
export default defineNuxtConfig({
  // ...其他設定
  app: {
    head: {
      viewport: "width=device-width, initial-scale=1", // 渲染出 <meta name="viewport" content="width=device-width, initial-scale=1">
      title: "全域 - Nuxt3 Day11  Global head 練習", // 渲染出 <title>全域 - Nuxt3 Day11  Global head 練習</title>
      charset: "utf-8", // 渲染出 <meta charset="UTF-8">
      meta: [
        // 渲染出 <meta name="description" content="透過今天的學習，將會學習到 Nuxt3  Global head  的設定方法">
        {
          name: "description",
          content: "透過今天的學習，將會學習到 Nuxt3  Global head  的設定方法 ",
        },
        // 渲染出 <meta property="og:title" content="Nuxt3 Day11  Global head 練習">
        { property: "og:title", content: "Nuxt3 Day11  Global head 練習" },
        { property: "og:url", content: "http://localhost:3000/" },
        {
          property: "og:description",
          content: "透過今天的學習，將會學習到 Nuxt3  Global head  的設定方法",
        },
      ],
      script: [
        // 從外部載入 lodash 套件
        // 渲染出 <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.21/lodash.js"></script>
        {
          src: "https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.21/lodash.js",
          // 用於調整 script 標籤渲染的位置，值可以是 'head' | 'bodyClose' | 'bodyOpen'
          tagPosition: 'head'
        },
      ],
      link: [
        // 從外部載入 google 字體
        // 渲染 <link rel="preconnect" href="https://fonts.googleapis.com">
        { rel: "preconnect", href: "https://fonts.gohogleapis.com" },

        // 渲染 <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
        {
          rel: "preconnect",
          href: "https://fonts.gstatic.com",
          crossorigin: "",
        },

        // 渲染  <link href="https://fonts.googleapis.com/css2?family=Noto+Sans+TC:wght@100..900&display=swap" rel="stylesheet">
        {
          rel: "stylesheet",
          href: "https://fonts.googleapis.com/css2?family=Noto+Sans+TC:wght@100..900&display=swap",
        },
      ],
      style: [
        // 渲染出 <style>h1{ color: red }</style>
        { children: "h1{ color: red }" },
      ],
      noscript: [
        // 渲染出 <noscript>此網頁需要支援 JavaScript 才能正確運行，請先至你的瀏覽器設定中開啟 JavaScript。</noscript>
        {
          children:
            "此網頁需要支援 JavaScript 才能正確運行，請先至你的瀏覽器設定中開啟 JavaScript。",
        },
      ],
    },
  },
});
```

範例中使用了 `viewport`、`title`、`charset`、`meta`、`script`、`link`、`style` 和 `noscript`  屬性 : 

- title :  設定全域的標題，在所有頁面元件都套用這個標題。
- viewport :  設定全域網頁的可見區域以及縮放比例。
- charset :  設定 HTML 的字元編碼為 utf-8 。
- meta: 設定 meta 標籤，例如 og:title 。
- script: 載入外部的 JavaScript 資源。其中調整 script 標籤渲染的位置可以使用 [tagPosition](https://unhead.unjs.io/usage/guides/positions#tagposition) 屬性，允許的值有  'head' ( 渲染在 `<head>` 標籤內，預設值)  、 'bodyClose'  ( 渲染在 `</body>` 結尾標籤前面 ) 、'bodyOpen’  ( 渲染在 `<body>` 起始標籤前面 )
- link:  載入外部的 CSS 資源。
- style: 定義內嵌樣式，渲染`<style></style>`標籤。
- noscript: 定義在 JavaScript 被禁用時顯示的內容，渲染 `<noscript></noscript>` 。

當設定 `meta`、`script`、`link`、`style` 和 `noscript` 屬性時，這些屬性的值都是以陣列格式呈現，且陣列中的每個元素都是物件格式。

在渲染時，`meta`、`script`、`link` 屬性會渲染相應的 HTML 標籤。陣列內的每個物件代表一個對應的 HTML 標籤，並包含該標籤的屬性和值。例如，`link` 屬性會渲染出 `link` 標籤，陣列中的每個物件都代表一個 `link` 標籤要設定的屬性，每個物件都會被渲染為一個 `link` 標籤，物件內的屬性會對應到 `link` 標籤的屬性。

而 `style` 和 `noscript` 屬性被渲染時，這些屬性名稱會分別生成 `<style>` 和 `<noscript>` 標籤。陣列中的每個元素都會創建一個相應的標籤。

 

### 渲染結果

加入全域設定後，在頁面可以透過 “檢視網頁原始碼” 查看 `/pages/index.vue` ( 首頁 ) 頁面渲染後的結果，如下圖。

![image](https://hackmd.io/_uploads/ry053FtGkx.png)



## 單一頁面 head 設定 (useHead)

上一節在  `nuxt.config.ts` 中設定的 head 資訊屬於全域設定，若希望單獨調整頁面的 head 資訊，可以使用 Nuxt3 提供的 `useHead`  Composable， 在單一頁面中設定 head 資訊。

```html
<script setup>
useHead({
  // 在物件內定義 head 資訊
});
</script>
```

### 撰寫 useHead 的語法

因為 useHead 也是基於 [Unhead](https://unhead.harlanzw.com/)  套件的格式進行撰寫，所以屬性的用法與撰寫結構和全域 `app.head` 屬性相同。若在頁面元件以 `useHead` 設定了與全域相同的屬性，`useHead` 撰寫的屬性會覆蓋全域的屬性，其他屬性則會沿用全域設定。

### 範例

例如在 `/pages/index.vue` 使用 `useHead` 加入了首頁的 head 資訊，會覆蓋全域 `title` 和 `meta` 屬性的設定。

```html

<!--  /pages/index.vue -->
<script setup>
useHead({
  title: "首頁 - Nuxt3 Day11 useHead() 練習",
  meta: [
    {
      property: "og:title",
      content: "首頁 - Nuxt3 Day11 useHead() 練習",
    },
    { property: "og:image", content: "http://localhost:3000/share.jpg" },
    {
      property: "og:description",
      content: "首頁 - 透過今天的學習，將會學習到 Nuxt3  useHead() 的使用方法 ",
    },
    {
      name: "description",
      content: "首頁 - 透過今天的學習，將會學習到 Nuxt3  useHead() 的使用方法 ",
    },
  ],
});
</script>

<template>
  <h1>Page: index</h1>
</template>
```

### 渲染結果

渲染的結果如下圖所示，左側是  `/pages/index.vue` 加入 useHead  之前以全域設定渲染的結果，右側是 `/pages/index.vue` 加入 useHead  之後渲染的結果。

在 `useHead()` 加入的 `title` 和 `meta` 會覆蓋全域 `title` 和 `meta` 的屬性。而其它在 `useHead()` 沒有寫入的屬性則是會繼續沿用全域的設定，例如 noscript、script、link 屬性。

![image](https://hackmd.io/_uploads/BkNXEaTbJl.png)


### 傳入具響應性的資料

`useHead()`  中所有的屬性都可以使用具有響應性的資料，包括 `ref`、`reactive`、`computed getter`。以 `/pages/index.vue`  的 `useHead()` 為例，可以將 `title` 屬性以 `ref` 定義，在模板中可以對 input 綁定 v-model=”title” 來動態修改瀏覽器頁籤的標題。

```html
<!--  /pages/index.vue -->
<script setup>
const title = ref("首頁 - Nuxt3 Day11 useHead() 練習");

useHead({
  title,
  meta: [
    {
      property: "og:title",
      content: "首頁 - Nuxt3 Day11 useHead() 練習",
    },
    { property: "og:image", content: "http://localhost:3000/share.jpg" },
    {
      property: "og:description",
      content: "首頁 - 透過今天的學習，將會學習到 Nuxt3  useHead() 的使用方法 ",
    },
    {
      name: "description",
      content: "首頁 - 透過今天的學習，將會學習到 Nuxt3  useHead() 的使用方法 ",
    },
  ],
});
</script>

<template>
  <h1>Page: index</h1>
  <label for="title">
    修改瀏覽器頁籤的標題
    <input type="text" id="title" v-model="title" />
  </label>
</template>
```
<br>

> 今日學習的[範例 Code - 資料夾: day11-nuxt-usehead-examplle](https://github.com/hexschool/nuxt-daily-tasks-2024) 


## 題目

請 fork  這一份 [模板](https://github.com/jasonlu0525/nuxt3-live-question/tree/day11-usehead-seo)，在  `nuxt.config.ts` 與 `/pages/room/index.vue`  ，完成以下條件 :

- 在 `nuxt.config.ts` 中定義全域設定，確保以下 head 資訊被應用於所有頁面。

```html

<title>Freyja | 高雄頂級旅館 - 提供奢華住宿體驗</title>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta http-equiv="X-Content-Type-Options" content="nosniff">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="author" content="Freyja 旅館">
<meta name="keywords" content="Freyja,Freyja 訂房,高雄旅遊,訂房,住宿,住宿預訂,四人房,雙人房,景觀房">
<meta name="description" content="Freyja 旅館位於高雄，提供頂級的住宿體驗。享受絕美市景與高級設施，讓您的每一刻都充滿奢華與舒適。立即預訂，開啟難忘的住宿之旅！">
<meta name="theme-color" content="#ffffff">
<meta name="robots" content="index, follow">

<link rel="icon" href="/favicon.ico">
<link rel="canonical" href="https://freyja.travel.com.tw">

<meta property="fb:app_id" content="12345678" /> 
<meta property="og:locale"   content="zh-TW" /> 
<meta property="og:type"   content="website" /> 

<meta property="og:url"    content="https://freyja.travel.com.tw" /> 
<meta property="og:title" content="Freyja | 高雄頂級旅館 - 提供奢華住宿體驗" /> 
<meta property="og:image" content="https://freyja.travel.com.tw/images/og-image.jpg" /> 
<meta property="og:description" content="Freyja 旅館位於高雄，提供頂級的住宿體驗。享受絕美市景與高級設施，讓您的每一刻都充滿奢華與舒適。立即預訂，開啟難忘的住宿之旅！" />
```

- 在 `/pages/room/index.vue` 頁面中，使用 `useHead` 渲染以下 head 資訊，確保覆蓋全域設定中的對應屬性。

```html
<title>Freyja | 房型列表</title>
<meta name="description" content="探索 Freyja 頂級房型，從景觀尊榮家庭房到尊爵雙人房，享受絕美市景與舒適空間。立即預訂，享受獨特的住宿體驗！">

<meta property="og:title" content="Freyja | 高雄最頂級的旅館">
<meta property="og:description" content="探索 Freyja 的高雄頂級房型，從景觀尊榮家庭房到尊爵雙人房，享受絕美市景與舒適空間。立即預訂，享受獨特的住宿體驗！">
<meta property="og:image" content="https://raw.githubusercontent.com/hexschool/2022-web-layout-training/main/typescript-hotel/%E6%A1%8C%E6%A9%9F%E7%89%88/room2-1.png">
<meta property="og:url" content="https://freyja.travel.com.tw/room">

<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:title" content="Freyja | 高雄最頂級的旅館">
<meta name="twitter:description" content="探索 Freyja 的高雄頂級房型，從景觀尊榮家庭房到尊爵雙人房，享受絕美市景與舒適空間。立即預訂，享受獨特的住宿體驗！">
<meta name="twitter:image" content="https://raw.githubusercontent.com/hexschool/2022-web-layout-training/main/typescript-hotel/%E6%A1%8C%E6%A9%9F%E7%89%88/room2-1.png">
```

- 確認 `/pages/room/index.vue` 頁面的 head 設定成功覆蓋了全域 head 中的相同屬性設定。

## 回報流程

將答案上傳至 GitHub 並複製 GitHub  repo 連結貼至底下回報就算完成了喔 !
解答位置請參考下圖（需打開程式碼的部分觀看）

![](https://i.imgur.com/vftL5i0.png)

<!--   

解答: https://github.com/jasonlu0525/nuxt3-live-answer/tree/day11-usehead-seo

-->

## 回報區

|       Discord |   Github  / 答案 |
| --- | --- |
| LinaChen | [Github](https://github.com/Lina-SHU/nuxt3-live-question) |
| 眼睛 | [Github](https://github.com/Thrizzacode/nuxt3-live-question/tree/day11-usehead-seo) |
| kevinhes | [Github](https://github.com/kevinhes/nuxt-daily-mission/tree/day11) |
| hsin yu | [Github](https://github.com/dogwantfly/nuxt3-daily-task-live-question/tree/day11-usehead-seo) |
| Jim Lin | [Github](https://github.com/junhoulin/Nuxt3-hw-day-after10/tree/day11) |
| Stan | [Github](https://github.com/haoxiang16/nuxt3-live-question/tree/day11-usehead-seo) |
| Steven | [Github](https://github.com/y7516552/nuxt3-live-question/tree/day11) |
| dragon | [Github](https://github.com/peterlife0617/2024-nuxt-training-homework01/tree/feature/day11) |
| MY | [Github](https://github.com/ahmomoz/nuxt3-live-question/tree/day11-usehead-seo-hw) |
| Rocky | [Github](https://github.com/WuRocky/Nuxt-Day11-Global-head-Settings-useHead.git) |
| Ariel | [Github](https://github.com/Ariel0508/nuxtday6/tree/nuxtday11) |
| Tough life | [GitHub](https://github.com/hakuei0115/Nuxt_testing) |
| wei_Rio |[Github](https://github.com/wei-1539/nuxtDaily10/tree/Day-11---Global-head-Settings-%26-useHead)|
| runweiting | [Github](https://github.com/runweiting/2024-NUXT-Task/tree/day11) |
| Fabio20 | [Github](https://github.com/fabio7621/nuxt3-live-question-d2/tree/nuxt-live-day11) |
| tanuki狸 | [Github](https://github.com/tanukili/Nuxt-2024-week01-2/tree/day11-usehead-seo) |
| 阿塔 | [Github](https://github.com/QuantumParrot/2024-Hexschool-Nuxt-Camp-Daily-Task/commit/d6ebef785da8a65a0d64e177855b4a4be3aa2206) |
| Nielsen | [Github](https://github.com/asz8621/nuxt3-daily-task/tree/day11-usehead-seo) |
| barry1104 | [Github](https://github.com/barrychen1104/nuxt3-live-question/tree/day11-usehead-seo) |
| Johnson | [Github](https://github.com/tttom3669/2024_hex_nuxt_daily/tree/day11-usehead-seo) |
| lidelin | [Github](https://github.com/Lide/nuxt3-live-question/tree/day11-usehead-seo) |
<!-- 
快速複製

| --- | [Github]() |

-->
