Chrome browser devtools Googlebot server error 無法載入頁面

·

2 min read

在這個檔案中,我看到 pathname computed property 直接訪問了 window 對象。在 SSR (Server-Side Rendering) 環境中這會導致錯誤,因為服務器端沒有 window 對象。我們需要修改這部分代碼:

主要改動:

  • 使用 process.client 檢查是否在客戶端環境

  • 在服務器端使用 Nuxt 的 $route.path 作為替代

這樣修改的好處是:

  • 避免 SSR 時的錯誤

  • 保持功能一致性

  • 提供更好的錯誤處理

另外,建議也添加一些錯誤處理:

computed: {
  pathname() {
    try {
      if (process.client) {
        return window.location.pathname
      }
      return this.$route.path
    } catch (error) {
      console.error('Error getting pathname:', error)
      return this.$route.path // 使用路由路徑作為後備
    }
  }
}

process.client 是 Nuxt.js 提供的一個全局變量,讓我們詳細解釋它:

1.什麼是 process.client?

  • if (process.client) { // 這段代碼只會在瀏覽器中執行 // window, document 等瀏覽器 API 在這裡是可用的}

2.為什麼需要它?

    • Nuxt.js 是一個同構框架(Isomorphic Framework)

      • 代碼會在兩個環境中運行:

        • 服務器端(SSR):Node.js 環境

        • 客戶端(Browser):瀏覽器環境

3.使用場景:

// 常見的使用場景
if (process.client) {
  // 瀏覽器 API
  window.addEventListener('scroll', ...)
  localStorage.setItem(...)
  document.querySelector(...)

  // 只想在客戶端載入的模塊
  require('some-browser-only-package')
}

4.對應的服務器端檢查:

if (process.server) {  
  // 這段代碼只會在服務器端執行  
  // Node.js API 在這裡是可用的
}

5.實際運作原理:

// 編譯後的代碼大致如下
const process = {
  client: typeof window !== 'undefined',
  server: typeof window === 'undefined'
}

錯誤處理最佳實踐:

computed: {
  pathname() {
    try {
      if (process.client) {
        return window.location.pathname
      }
      // 服務器端後備方案
      return this.$route.path
    } catch (error) {
      console.error('pathname error:', error)
      return this.$route.path
    }
  }
}

生命週期中的使用:

export default {
  mounted() {
    // mounted 只在客戶端執行,所以這裡不需要 process.client 檢查
    window.addEventListener('resize', this.handleResize)
  },

  beforeDestroy() {
    // 同樣,beforeDestroy 也只在客戶端執行
    window.removeEventListener('resize', this.handleResize)
  },

  asyncData() {
    // asyncData 只在服務器端執行,這裡不需要 process.server 檢查
  }
}
  1. 常見陷阱:
// ❌ 錯誤寫法
data() {
  return {
    windowWidth: window.innerWidth // 會在 SSR 時報錯
  }
}

// ✅ 正確寫法
data() {
  return {
    windowWidth: process.client ? window.innerWidth : 0
  }
}
  1. 性能考慮:
// 條件編譯:webpack 會在打包時移除未使用的代碼
if (process.client) {
  // 這段代碼不會包含在服務器端的包中
  require('heavy-browser-only-library')
}
  1. 調試技巧:

    // 可以用來檢查當前運行環境
    console.log('Current environment:', {
      isClient: process.client,
      isServer: process.server,
      hasWindow: typeof window !== 'undefined'
    })
    

這個機制是 Nuxt.js 同構應用的核心特性之一,正確使用它可以:

  • 避免 SSR 相關錯誤

  • 優化代碼大小

  • 提高應用性能

  • 改善開發體驗