當前位置: 妍妍網 > 碼農

原來在 Vue、React 頁面中管理 標簽這麽簡單!

2024-05-08碼農

單頁套用(SPA)以其出色的使用者體驗和流暢的頁面切換效果在現代Web開發中備受青睞。然而,與傳統的多頁套用相比,SPA 在頁面結構和資源管理上存在一些獨特的挑戰。

其中一個常見的問題是如何在 SPA 中高效地管理頁面的 <head> 標簽,包括動態設定頁面標題、元資訊、樣式表連結等。 本文就來看看如何在 Vue 和 React 計畫中更加簡單、高效的管理 <head> 標簽!

前言

React 和 Vue 主要被用於構建單頁套用。在單頁套用中,所有頁面或檢視實際上都是在一個單一的HTML頁面上動態渲染的,而不是像傳統多頁套用那樣透過伺服器載入不同的HTML頁面。因此,不能簡單地在每個HTML頁面上靜態地設定 <head> 標簽,因為這些標簽是共享的,且需要動態地根據當前顯示的頁面或檢視進行更新。

目前,Vue 和 React 等前端框架都是不支持的為每個頁面添加 <head> 標簽的,需要借助第三方工具庫來動態地管理單頁套用中的 <head> 標簽。這些庫允許在元件級別定義和更新標簽的內容,當元件掛載、更新或解除安裝時,它們會相應地修改DOM中的 <head> 標簽。

註意:在即將到來的 React 19 中,將預設支持在頁面中添加 <head> 標簽。

那什麽場景下需要在套用中動態管理 <head> 標簽呢?

  • SEO最佳化 :搜尋引擎最佳化(SEO)要求每個頁面或檢視都有獨特的標題( <title> )和描述( <meta name="description"> )。當使用者在SPA中導航到不同的頁面或檢視時,可能需要動態地更新這些標簽以反映當前頁面的內容。

  • 社交媒體分享 :當使用者分享 SPA 頁面到社交媒體平台時,平台通常會從頁面的標簽中提取標題、描述和圖片等資訊來生成分享卡片。因此,可能需要為每個頁面或檢視設定不同的社交媒體後設資料(如 <meta property="og:title"> <meta property="og:description"> <meta property="og:image"> ),以便在分享時顯示正確的資訊。

  • CSS樣式和連結 :在SPA中,可能需要根據當前頁面或檢視的需求動態地載入不同的CSS樣式表或樣式連結。透過在中添加或刪除 <link rel=" stylesheet"> 標簽,可以實作這一點。

  • JavaScript指令碼 :與CSS類似,可能需要根據當前頁面或檢視的需求動態地載入不同的JavaScript指令碼。透過在中添加或刪除 <script> 標簽,可以控制哪些指令碼在當前頁面或檢視中可用。

  • 其他後設資料 :除了上述常見的後設資料外,還有其他一些情況可能需要動態管理 <head> 標簽。例如,可能需要為不同的頁面或檢視設定不同的字元集( <meta charset="UTF-8"> )、視口設定( <meta name="viewport"> )或行動應用圖示( <link rel="apple-touch-icon"> )。

  • 多語言支持 :在國際化(i18n)和多語言支持的場景中,可能需要根據使用者選擇的語言動態地更新頁面的標題、描述和其他後設資料。

  • A/B測試 :在進行A/B測試時,可能需要為不同的使用者組或流量來源顯示不同的頁面標題、描述或樣式。透過動態管理標簽,可以輕松地實作這一點。

  • 跟蹤和分析 :在某些情況下,可能需要在 <head> 標簽中添加特定的跟蹤程式碼或分析指令碼(如Google Analytics的跟蹤程式碼),以便收集有關使用者行為和其他關鍵指標的數據。

  • Unhead

    Unhead 是 unjs 工具集中的一個工具,用於管理網站 <head> 部份的庫,它同時支持伺服端渲染(SSR)和客戶端渲染(CSR)。為了提升模組化和靈活性,Unhead 被拆分為多個獨立的包,使開發者能夠按需選擇和使用所需的元件。核心包不依賴於任何特定框架,因此可以在任何環境中無縫執行。

    此外,為了增強在特定框架下的使用體驗,Unhead 還提供了框架專用包。這些包簡化了與框架的整合,使開發者能夠更高效地利用 Unhead 的功能。

    官網: https://unhead.unjs.io/

    React Helmet

    React Helmet 是一個在建立 React 套用時用來管理HTML文件 <head> 部份的外掛程式。它允許向 HTML 文件添加額外的元素,如 title meta link script 等,可以將Helmet看作是一個放置於元件樹頂部的特殊元件,用來管理頁面頭部。

    React Helmet的特點包括:

  • 支持所有有效的 <head> 標簽: title base meta link script noscript style 標簽。

  • 支持 body、html 和 title 標簽的內容。

  • 支持伺服端渲染。

  • 巢狀的元件會覆蓋重復的 <head> 變更。

  • 當在相同元件中指定時,重復的 <head> 變更會被保留(支持像 "apple-touch-icon" 這樣的標簽)。

  • 提供用於跟蹤 DOM 變更的回呼函式。

  • import React from"react";
    import{Helmet}from"react-helmet";
    classApplicationextendsReact.Component{
    render(){
    return(
    <div className="application">
    <Helmet>
    <meta charSet="utf-8"/>
    <title>My Title</title>
    <link rel="canonical" href="http://mysite.com/example"/>
    </Helmet>
    ...
    </div>
    );
    }
    };

    Github: https://github.com/nfl/react-helmet

    react-helmet-async

    這個庫是基於 React Helmet 的一個改進版本。 <Helmet> 的使用方式保持不變,但為了實作更好的狀態管理,現在伺服器和客戶端都需要使用 <HelmetProvider> 來封裝每個請求的狀態。

    React Helmet 原本依賴於 react-side-effect,但考慮到它並不是執行緒安全的,如果在伺服端進行任何異步操作,需要一個能夠按請求封裝數據的解決方案。這個庫正是為了滿足這一需求而設計的,它確保了狀態的安全性並提高了效能。

    import React from'react';
    import ReactDOM from'react-dom';
    import{ Helmet, HelmetProvider }from'react-helmet-async';
    const app =(
    <HelmetProvider>
    <App>
    <Helmet>
    <title>Hello World</title>
    <link rel="canonical" href="https://www.tacobell.com/"/>
    </Helmet>
    <h1>Hello World</h1>
    </App>
    </HelmetProvider>
    );
    ReactDOM.hydrate(
    app,
    document.getElementById(‘app’)
    );

    Github: https://github.com/staylor/react-helmet-async