Nuxt(1) - SEO設定 & router


Posted by TempuraEngineer on 2022-09-10

目錄


Nuxt是甚麼

Nuxt是Vue的框架,就像Next之於React,它們都是為了解決SPA網站SEO問題而生的

但其SSR(universal)模式並不是完全的SSR,而是只有第一頁採SSR,其他頁還是CSR的,如此便能兼顧SEO與使用者體驗

// nuxt.config.js

export default {
  // 預設為true,即SSR。如果要CSR再設為false
  // 以前可以有mode屬性設為universal或SPA,但該屬性現在已經廢棄
  ssr: false 
}

至於SPA SEO差的原因則是和CSR有關,CSR走virtual DOM的形式

CSR畫面的渲染全由JS在客戶端上完成,也就是說伺服器返回的HTML的是沒有內容的(如圖)

而且建專案的時候還有UI lib、module、linter可以選

關於SSR和CSR滿長的,之後放到另一篇


Meta Tags & SEO

Nuxt提供3種方式設定meta標籤的內容

  1. 全域設定

以星宇航空的官網為例,設定可能會長這樣

// nuxt.config.js

export default {
  head: {
    // Maps to the inner-text value of the <title> element.
    // If titleTemplate is used, the value of title will be injected into the %s placeholder in titleTemplate before being rendered.
    title: '星宇航空 - STARLUX Airlines',
    // Each item in the array maps to a newly-created <meta> element, where object properties map to attributes.
    meta: [
      { charset: 'utf-8' },
      { name: 'viewport', content: 'width=device-width, initial-scale=1, maximum-scale=5' },
      { httpEquiv: 'X-UA-Compatible', content:'IE=edge' },
      {
        hid: 'og:image', // og:image,分享網頁時會顯示的縮圖
        name: 'https://webassets.starlux-airlines.com/zh-TW/Images/1118_banner_tcm5-4452.png',
        property: 'og:image'
      },       
      {
        hid: 'og:title', // og:title,網頁標題
        name: '星宇航空 - STARLUX Airlines',
        property: 'og:title'
      },
      {
        hid: 'og:type', // og:type,內容的媒體類型,預設為 website
        name: 'article',
        property: 'og:type'
      },
      {
        hid: 'description',
        name: '星宇航空提供飛往東北亞、東南亞...',
        name: 'description'
      },            
      // 其他省略
    ],
    // Each item in the array maps to a newly-created <link> element, where object properties map to attributes.
    link: [{ rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' }]
  }
}
  1. 個別頁面設定
<script>
export default {
  head: {
    title: 'Home',
    meta: [
      {
        hid: 'description',
        name: 'name',
        content: 'this is content'
      }
    ],
  }
}
</script>


router & NuxtLink

Nuxt會根據pages資料夾的結構自動產生router

Nuxt automatically generates the vue-router configuration for you, based on your provided Vue files inside the pages directory

例如以下的結構

├─pages
│  └─User
│     ├─ index.vue
│     └─ UserDetail.vue
├─ index.vue
└─ About.vue
router: {
  routes: [
    {
      path: '/about',
      component: 'pages/about.vue',
      name: 'about'
    }, 
    {
      path: '/User',
      component: 'pages/User/index.vue',
      name: 'User'
    }, 
    {
      path: '/User/UserDetail',
      component: 'pages/User/UserDetail.vue',
      name: 'User-UserDetail'
    }, 
    {
      path: '/',
      component: 'pages/index.vue',
      name: 'index'
    }
  ]
}


動態

有時可能會需要動態router,這時還是可以自行設定

當Nuxt版本>2.13時,只要在檔名、資料夾開頭加上_就會自動生成動態router

├─pages
│  └─User
│     ├─ index.vue
│     └─ _UserDetail.vue
├─ User.vue
(other files)
{
  name: 'User-UserDetail',
  path: '/User/:UserDetail',
  component: 'pages/User/_UserDetail.vue'
},

只要加上_.vue,甚至可以做到長度不確定時的動態路由(ex:/Product/table/123, Product/chair/wood/999)

├─pages
│  └─User
│     ├─ index.vue
│     └─ _UserDetail.vue
├─ User.vue
├─ _.vue
(other files)
// /Product/table/123, Product/chair/wood/999都會到_.vue

{
  path: "/*",
  component: 'pages/_.vue',
  name: "all"
}


巢狀

如果需要巢狀路由(nested router),則需要開一個和資料夾同名的.vue檔,並在.vue內放NuxtChild

NuxtChild的功能為展示child component,和RouterView一樣

<div class="container">
  this is User.vue

  <NuxtLink class="ml-4" to="/User/Profile">Profile</NuxtLink>
  <NuxtLink class="ml-4" to="/User/:UserDetail">UserDetail</NuxtLink>

  <hr class="my-4">

  <!-- 加上keep-alive prop就和<KeepAlive><RouterView/></KeepAlive>一樣 -->
  <NuxtChild keep-alive></NuxtChild>
</div>
├─pages
│  └─User
│     ├─ Profile.vue
│     └─ _UserDetail.vue
(other files)
{
  path: '/User',
  component: 'pages/User',
  children: [{
    path: 'Profile',
    component: 'pages/User/Profile.vue'
    name: 'User-Profile'
  }, {
    path: ':UserDetail',
    component: 'pages/User/_UserDetail.vue'
    name: 'User-UserDetail' 
  }]
}


NuxtLink

NuxtLink和RouterLink功能差不多,只差在prefetch的功能

prefetch就是在偵測到頁面上的 NuxtLink 時就先把NuxtLink 連到的頁面的script抓下來,所以頁面載入速度會快一點,但在無網路的或2G網路的情況下並不會prefetch

Nuxt automatically includes smart prefetching. That means it detects when a link is visible, either in the viewport or when scrolling and prefetches the JavaScript for those pages so that they are ready when the user clicks the link. Nuxt only loads the resources when the browser isn't busy and skips prefetching if your connection is offline or if you only have 2g connection.

如果不想要prefetch有2種方式關掉

  1. prefetch prop
<NuxtLink to='/about' no-prefetch>About page not pre-fetched</NuxtLink>

// Since Nuxt v2.10.0, you can also use the prefetch prop set to false
<NuxtLink to='/about' :prefetch='false'>About page not pre-fetched</NuxtLink>
  1. 全域設定
// nuxt.config.js

export default {
  router: {
    prefetchLinks: false
  }
}

另外如果如果要設定樣式的話可以使用.nuxt-link-active, .nuxt-link-exact-active, .nuxt-link-prefetched,樣式則放在main.css,然後再全域引入

如果想要自訂class name也可以


參考資料

Nuxt - Create Nuxt App

Nuxt - router

Nuxt - meta
Nuxt - SEO HTML head


#Nuxt







Related Posts

初試啼聲,只用原生 JS 跟 CSS 寫「口罩地圖 」Ep.04

初試啼聲,只用原生 JS 跟 CSS 寫「口罩地圖 」Ep.04

D9_判斷式、迴圈、函式

D9_判斷式、迴圈、函式

Introduction to gRPC

Introduction to gRPC


Comments