Astro 專題 - 多語系商品探索儀表板 (Multi-lang Product Explorer) - 1

更新 發佈閱讀 28 分鐘

環境架構設計

  • astro v5
  • tailwind v4
  • vercel 佈署

第一階段:環境初始化

1. 建立專案

打開終端機,執行 Astro 建立指令:

npm create astro@latest my-product-explorer
# 選擇:Empty project
# 選擇:Yes (Install dependencies)
# 選擇:Yes (TypeScript - Strict)

2. 安裝 Tailwind v4

在 v4 中,我們不再使用舊的 @astrojs/tailwind 整合包,而是直接使用 Vite 插件:

npm install tailwindcss @tailwindcss/vite

3. 安裝 vercel

npx astro add vercel

安裝這個適配器主要是為了將 Astro 從「靜態產生」轉向 SSR(伺服器端渲染) 或混合模式。它的主要優點包括:

  • SSR 支援:讓你可以在 Vercel 的 Edge Network 或 Serverless Functions 上執行後端程式碼(例如處理登入、API 請求)。
  • 預覽功能:支援 Vercel 的「草稿模式(Draft Mode)」。
  • 影像優化:自動與 Vercel 的圖片優化服務整合。
  • 中介軟體 (Middleware):讓你能直接在 Vercel 邊緣節點執行邏輯。

💡 Serverless Functions :詳見 額外筆記-⭐ Serverless Functions

4. 設定 astro.config.mjs

將 Tailwind 整合進 Vite 配置:

import { defineConfig } from 'astro/config'
import tailwindcss from '@tailwindcss/vite'
import vercel from '@astrojs/vercel'

export default defineConfig({
adapter: vercel(),
output: 'server', // 為了儀表板,通常建議使用 SSR 或 Hybrid
vite: {
plugins: [tailwindcss()],
},
i18n: {
defaultLocale: 'en',
locales: ['en', 'zh-tw'],
routing: {
prefixDefaultLocale: false,
},
},
})

💡 i18n :詳見 額外筆記-⭐ i18n (國際化多語系)

第二階段:Tailwind v4 CSS-First 配置

在 src/styles/global.css 中,直接引入 Tailwind 並定義主題:

@import 'tailwindcss';

@theme {
/* 定義儀表板專用顏色 */
--color-dashboard-bg: #f8fafc;
--color-brand: #3b82f6;
}

/* v4 不再需要 @tailwind base/components/utilities; 只要 @import 即可 */

在你的 Layout 檔案(如 src/layouts/Layout.astro)中引入此 CSS:

---
import '../styles/global.css';
---
<html>...</html>

第三階段:實作多語系商品資料 (Content Layer)

Astro v5 強大的地方在於 Content Layer

1. 定義 Schema

在 src/content/config.ts 定義商品資料結構:

import { defineCollection, z } from 'astro:content'
import { glob } from 'astro/loaders'

const products = defineCollection({
loader: glob({
pattern: '**/[^_]*.{md,mdx}',
base: './src/content/products',
}),
schema: z.object({
title: z.string(),
description: z.string(),
price: z.number(),
category: z.string(),
}),
})

export const collections = { products }

💡 'astro:content' 錯誤訊息 :
可詳見 額外筆記-⚠️ 如果 "astro:content" IDE 出現錯誤

💡 glob :
可詳見 額外筆記-⭐ import { glob } from 'astro/loaders';

💡 collections :
可詳見 額外筆記-⭐ export const collections = { products }

2. 檔案結構

建立多語系資料夾:

  • src/content/products/en/iphone.md
    ---
    title: 'iPhone 15 Pro'
    description: 'Experience the next generation of iPhone with Titanium design and A17 Pro chip.'
    price: 999
    category: 'Smartphones'
    ---

    ## Product Features

    - **Titanium Design**: Strong and light.
    - **A17 Pro Chip**: A monster win for gaming.
    - **Camera**: 48MP Main camera for super-high-resolution photos.

    This is the English version of the product description.
  • src/content/products/zh-tw/iphone.md
    ---
    title: 'iPhone 15 Pro'
    description: '體驗配備鈦金屬設計與 A17 Pro 晶片的次世代 iPhone。'
    price: 36900
    category: '智慧型手機'
    ---

    ## 產品特點

    - **鈦金屬設計**:堅固且輕盈。
    - **A17 Pro 晶片**:遊戲效能的巨大飛躍。
    - **相機系統**4800 萬像素主相機,打造超高解析度照片。

    這是產品說明的繁體中文版本。

第四階段:建立導覽與儀表板 UI

1. 語言切換組件

建立 src/components/LanguagePicker.astro:

---
const languages = { en: 'English', 'zh-tw': '繁體中文' };
---
<ul class="flex gap-4">
{Object.entries(languages).map(([code, label]) => (
<li>
<a href={`/${code}/`} class="text-brand hover:underline">{label}</a>
</li>
))}
</ul>

2. 商品列表頁碼

在 src/pages/[lang]/products.astro:

---
import { getCollection } from 'astro:content';
export async function getStaticPaths() {
return [{ params: { lang: 'en' } }, { params: { lang: 'zh-tw' } }];
}
const { lang } = Astro.params;
const allProducts = await getCollection('products', ({ id }) => id.startsWith(lang));
---
<div class="p-8 bg-dashboard-bg min-h-screen">
<h1 class="text-3xl font-bold mb-6">Product Explorer</h1>
<div class="grid grid-cols-1 md:grid-cols-3 gap-6">
{allProducts.map(product => (
<div class="bg-white p-4 rounded-xl shadow-sm border border-gray-200">
<h2 class="text-xl font-semibold">{product.data.title}</h2>
<p class="text-gray-500">{product.data.description}</p>
<div class="mt-4 font-mono text-brand">${product.data.price}</div>
</div>
))}
</div>
</div>

💡 getCollection :
可詳見 額外筆記-⭐ const allProducts = await getCollection('products', ({ id }) => id.startsWith(lang));

💡 getCollection 錯誤訊息 :
可詳見 額外筆記-⚠️ 如果 ...getCollection... IDE 出現錯誤

第五階段:Vercel 佈署

1. 提交至 GitHub:

git init
git add .
git commit -m "feat: init multi-lang dashboard"

2.連結 Vercel:

  • 登入 Vercel。
  • 點擊 Add New Project,導入你的 GitHub 倉庫。
  • Vercel 會自動偵測 Astro 框架,並使用 npm run build 進行構建。

📚 額外筆記

⭐ Serverless Functions

Serverless Functions(無伺服器函數)是一種雲端運算模型,讓你只需要編寫程式碼(函數),而不需要管理底層的伺服器硬體或作業系統。
雖然名字叫「無伺服器」,但並不是真的沒有伺服器,而是伺服器管理的所有瑣事都由雲端供應商(如 AWS, Google Cloud)幫你處理好了

💡 核心特點:為什麼它很受歡迎?

1. 事件驅動 (Event-Driven): 函數平常是不運行的,只有在特定的「事件」觸發時才會啟動。例如:有人上傳照片、呼叫了 API、或是定時排程。

2. 自動擴展 (Auto-scaling): 如果你的網站突然湧入一萬個人,雲端系統會自動幫你啟動一萬個函數實例;沒人用的時候,它會縮減到零。

3. 按量計費 (Pay-as-you-go): 你只按照程式碼「執行」的時間付費。如果程式沒跑,你一分錢都不用花。這跟傳統租用伺服器(不管有沒有人用都要付月費)完全不同。

4. 無狀態 (Stateless): 函數執行完就會消失,不會記住上次的狀態。如果需要儲存資料,必須另外存到資料庫或雲端硬碟。

💡 常見的使用場景

  • 圖片處理: 使用者上傳照片後,自動產生縮圖。
  • API 後端: 處理簡單的網頁請求(如登入、查詢訂單)。
  • 定時任務: 每天早上 8 點自動抓取天氣預報並發送通知。
  • 數據清洗: 將進入資料庫的原始數據進行即時格式轉換。

💡 著名的服務供應商

目前市面上最主流的 Serverless Functions 服務包括:

  • AWS Lambda (業界最領先)
  • Google Cloud Functions
  • Azure Functions
  • Vercel / Netlify Functions (前端開發者常用)

⭐ i18n (國際化多語系)

...

export default defineConfig({
  ...
  i18n: {
    defaultLocale: 'en',
    locales: ['en', 'zh-tw'],
    routing: {
      prefixDefaultLocale: false,
    },
  },
})

1. defaultLocale: "en"
這定義了網站的 預設語言

    • 在這裏,你的主要語系設定為英文。
    • 當使用者訪問根目錄(例如 example.com/)時,系統會預設提供英文內容。

2. locales: ["en", "zh-tw"]
這定義了網站 支援的所有語系

    • 你的網站目前支援兩種語言:英文 (en) 和 繁體中文 (zh-tw)。
    • Astro 會根據這個清單來產出對應的路由路徑。

3. routing: { prefixDefaultLocale: false }
這是關於 URL 網址路徑 的關鍵設定,決定了「預設語言」是否要在網址中顯示前綴(Prefix)。

    • 設定為 false (目前的狀態):英文(預設):網址不會有前綴。例如:example.com/about中文:網址會有前綴。例如:example.com/zh-tw/about
    • 如果設定為 true:英文:網址也會帶前綴。例如:example.com/en/about中文:保持不變。例如:example.com/zh-tw/about

⚠️ 如果 "astro:content" IDE 出現錯誤

Cannot find module 'astro:content' or its corresponding type declarations.

這個錯誤在 Astro 開發中非常常見,通常是因為 TypeScript 找不到自動生成的類型定義檔,或者是專案尚未進行第一次編譯。
以下是修復這個問題的步驟,按優先順序排列:

① 執行開發指令 (最有效)

Astro 的內容集合(Content Collections)類型是動態生成的。你需要執行一次開發伺服器或建構指令,讓 Astro 產生 .astro/ 資料夾裡的類型定義。
請在終端機執行:

npm run dev
# 或者
npx astro sync

astro sync 專門用於同步類型(如 astro:content),執行完後通常錯誤就會消失。

② 檢查 tsconfig.json

Astro 依賴 tsconfig.json 來對應路徑。請確保你的設定檔中有繼承 Astro 的預設設定:

{
"extends": "astro/tsconfigs/strict",
"compilerOptions": {
"baseUrl": ".",
"paths": {
"astro:content": ["./.astro/types.d.ts"]
}
}
}

注意: 如果你的 tsconfig.json 缺少 "extends": "astro/...",TypeScript 就不知道去哪裡找 astro:content

③ 重啟 VS Code 的 TS 伺服器

有時候檔案已經產生了,但 VS Code 還沒反應過來。

  1. 在 VS Code 按下 Ctrl + Shift + P (Mac 是 Cmd + Shift + P)。
  2. 輸入並選擇 "TypeScript: Restart TS Server"

④ 確認 src/content/config.ts 是否存在

astro:content 需要你定義了內容設定才會生效。請確認你有這個檔案:

  • 路徑:src/content/config.ts
  • 內容範例:
    import { defineCollection, z } from 'astro:content'
    const blog = defineCollection({
    /* ... */
    })
    export const collections = { blog }

⭐ import { glob } from 'astro/loaders';

這是在 Astro 5.0 版本引入的新功能:Content Layer API 中的一部分。

簡單來說,glob 是一個載入器(Loader),它讓你可以用更現代、效能更好的方式,將專案中的本地檔案(如 Markdown、JSON、YAML)載入到 Astro 的「內容集合(Content Collections)」中。

💡 它與舊版的區別

在 Astro 舊版本中,你不需要寫 loader,只要把檔案放在 src/content/ 下,系統會自動抓取。但在 Astro 5 中,透過 glob,你可以有更高的彈性:

  • 1. 檔案位置不再受限:你的 Markdown 檔案可以放在專案的任何地方(例如 src/data/ 或 src/posts/),不再強制只能放 src/content/
  • 2. 效能優化:它只會掃描你指定的檔案路徑,並且在處理大量資料時速度更快。
  • 3. 自定義模式:你可以精確控制哪些檔案要被當作內容。

⭐ export const collections = { products };

collections

是 Astro 框架的約定優於配置 (Convention over Configuration) 設計。

src/content/config.ts 是一個特殊的檔案,Astro 的內部引擎會專門去讀取這個檔案,並尋找名為 collections 的導出物件。

💡 為什麼一定要用 collections

  1. 框架進入點:當你執行 npm run dev 或 npx astro sync 時,Astro 會去檢查 src/content/config.ts。它預期會看到一個 export const collections,並以此來產生你之前看到的 astro:content 類型定義。
  2. 類型安全 (TypeScript):如果你改名成 const tests,Astro 就找不到你的定義,這會導致:
    • 你無法使用 getCollection('products')(因為系統不知道有這個集合)。
    • 你會看到你之前遇到的錯誤:Cannot find module 'astro:content'

💡 總結
在 Astro 的 src/content/config.ts 檔案中,export const collections 是固定語法


⭐ const allProducts = await getCollection('products', ({ id }) => id.startsWith(lang));

這行程式碼是在 Astro 中用來從內容集合(Content Collections)中篩選特定語言內容的邏輯。

簡單來說,它是在告訴 Astro:「請幫我從 products 這個集合裡,找出所有 id 是以當前語言(lang)開頭的資料。」

💡 詳細拆解

這行程式碼由三個核心部分組成:

  1. getCollection('products', ...)
    這是 Astro 內建的函式,用來獲取你在 src/content/config.ts 中定義的 products 集合裡的所有資料。
  2. ({ id }) => id.startsWith(lang) (篩選函式)
    這是 getCollection 的第二個參數,一個過濾器(Filter)
    • { id }:這是從每一筆產品資料中解構出來的「識別碼」。在 Astro 中,如果你的檔案路徑是 src/content/products/zh-tw/apple.md,那麼它的 id 通常就是 zh-tw/apple
    • id.startsWith(lang):這是一個條件判斷。如果 lang 的值是 "zh-tw",它就會檢查該產品的 ID 是不是由 "zh-tw" 開頭。
  1. await
    因為讀取檔案內容是異步操作(Async),所以需要配合 await 等待資料讀取完畢。

💡 為什麼要這樣寫? (多語系應用場景)

當你在做多語系(i18n)網站時,通常會把不同語言的文章放在對應的資料夾:

src/content/products/
├── en/
│ └── iphone.md (ID: "en/iphone")
└── zh-tw/
└── iphone.md (ID: "zh-tw/iphone")

如果你現在的頁面是中文版(lang = "zh-tw"),這行程式碼就能確保 allProducts 裡面只會拿到中文的產品資料,而不會把英文版的也抓進來。

💡 舉個例子
假設 lang = "en"

  • "en/iphone".startsWith("en") → True (保留)
  • "zh-tw/iphone".startsWith("en") → False (排除)

⚠️ 如果 ...getCollection... IDE 出現錯誤

const allProducts = await getCollection('products', ({ id }) =>
id.startsWith(lang)
)

❗ 'products' IDE 出現錯誤

No overload matches this call.
Overload 1 of 2, '(collection: never, filter?: ((entry: never) => entry is never) | undefined): Promise<never[]>', gave the following error.
Argument of type '"products"' is not assignable to parameter of type 'never'.
Overload 2 of 2, '(collection: never, filter?: ((entry: never) => unknown) | undefined): Promise<never[]>', gave the following error.
Argument of type '"products"' is not assignable to parameter of type 'never'.

看到 Argument of type '"products"' is not assignable to parameter of type 'never' 這個錯誤,

通常代表 TypeScript 雖然讀到了程式碼,但 Astro 沒能成功把你的 products 設定轉換成類型定義

簡單來說:TypeScript 覺得你的內容集合(Collections)是空的,所以你給它任何名字(如 "products"),它都認為是不存在的(never)。

請按照以下順序檢查並修復:

① 檢查 src/content/config.ts 的導出

最常見的原因是 config.ts 寫法不標準。請確認你的檔案看起來像這樣:

import { defineCollection, z } from 'astro:content'
import { glob } from 'astro/loaders' // 如果是 Astro 5.0+

const products = defineCollection({
loader: glob({ pattern: '**/*.{md,mdx}', base: './src/content/products' }),
schema: z.object({
title: z.string(),
// ... 其他欄位
}),
})

// 必須叫這個名字,且必須 export
export const collections = {
products: products,
}

② 執行 sync 指令 (強制重新產生類型)

這是解決 never 錯誤最有效的方法。Astro 需要在 .astro/ 資料夾生成隱藏的類型檔案。
請在終端機執行:

npx astro sync

③ 檢查檔案路徑與副檔名

如果你的 loader 設定的路徑下沒有任何檔案,Astro 有時會推斷該集合為空,導致類型變成 never

  • 確認 ./src/content/products 資料夾裡真的有 .md 或 .mdx 檔案。
  • 確認檔案內容是否有正確的 Frontmatter(標題、日期等),且符合你定義的 schema

④ VS Code 的快取問題

有時候檔案產生了,但 TypeScript 沒跟上:

  1. 開啟 src/pages/... 那個報錯的檔案。
  2. 按 F1 或 Ctrl+Shift+P
  3. 輸入 TypeScript: Restart TS Server 並執行。

💡 為什麼會報 never 錯誤?

在 TypeScript 中,當一個聯集型別(Union Type)沒有任何選項時,它會變成 never

  • 正常情況collection 參數應該是 'products' | 'blog' | 'news'
  • 錯誤情況:因為 Astro 沒抓到 config.ts 的內容,這個清單變成了空的,TypeScript 就會標示為 never
留言
avatar-img
李昀瑾的沙龍
0會員
37內容數
李昀瑾的沙龍的其他內容
2026/01/29
第三題:跨框架同步(React 與 Vue 的對話) 這是 Nano Stores 最強大的地方。假設你有一個專案,因為歷史原因或團隊偏好,同時使用了 React 和 Vue。 練習目標 建立一個 React 的輸入框(Input)。 建立一個 Vue 的預覽文字(Preview)。 當
2026/01/29
第三題:跨框架同步(React 與 Vue 的對話) 這是 Nano Stores 最強大的地方。假設你有一個專案,因為歷史原因或團隊偏好,同時使用了 React 和 Vue。 練習目標 建立一個 React 的輸入框(Input)。 建立一個 Vue 的預覽文字(Preview)。 當
2026/01/27
第二題:深色模式(Dark Mode) 深色模式(Dark Mode) 的核心在於如何讓狀態「持久化」(即使重新整理網頁,設定也不會消失),以及如何與系統或手動設定同步。 在 Nano Stores 中,我們可以使用原生提供的 persistent 擴充功能,這能讓我們省去手寫 localSto
2026/01/27
第二題:深色模式(Dark Mode) 深色模式(Dark Mode) 的核心在於如何讓狀態「持久化」(即使重新整理網頁,設定也不會消失),以及如何與系統或手動設定同步。 在 Nano Stores 中,我們可以使用原生提供的 persistent 擴充功能,這能讓我們省去手寫 localSto
2026/01/25
第一題:「購物車」系統 這個練習的重點在於學習如何使用 map 來處理物件型態的狀態,以及如何在多個元件之間同步這些數據。 練習目標 建立一個商品清單,點擊「加入」按鈕時更新購物車。 若商品已在購物車,數量 +1+1;若不在,則新增一筆。 即時顯示購物車內的商品總數。 第一步:建立
2026/01/25
第一題:「購物車」系統 這個練習的重點在於學習如何使用 map 來處理物件型態的狀態,以及如何在多個元件之間同步這些數據。 練習目標 建立一個商品清單,點擊「加入」按鈕時更新購物車。 若商品已在購物車,數量 +1+1;若不在,則新增一筆。 即時顯示購物車內的商品總數。 第一步:建立
看更多
你可能也想看
Thumbnail
《轉轉生》(Re:INCARNATION)為奈及利亞編舞家庫德斯.奧尼奎庫與 Q 舞團創作的當代舞蹈作品,結合拉各斯街頭節奏、Afrobeat/Afrobeats、以及約魯巴宇宙觀的非線性時間,建構出關於輪迴的「誕生—死亡—重生」儀式結構。本文將從約魯巴哲學概念出發,解析其去殖民的身體政治。
Thumbnail
《轉轉生》(Re:INCARNATION)為奈及利亞編舞家庫德斯.奧尼奎庫與 Q 舞團創作的當代舞蹈作品,結合拉各斯街頭節奏、Afrobeat/Afrobeats、以及約魯巴宇宙觀的非線性時間,建構出關於輪迴的「誕生—死亡—重生」儀式結構。本文將從約魯巴哲學概念出發,解析其去殖民的身體政治。
Thumbnail
Nuxt.js 是以 Vue 為基底所建構的框架,透過 Nuxt.js,我們能夠更輕鬆地開發靜態頁面 (Static Site)、操作體驗良好的單頁式網站 (SPA)、甚至是顧及 SEO 的伺服器端渲染 (SSR) 網站。
Thumbnail
Nuxt.js 是以 Vue 為基底所建構的框架,透過 Nuxt.js,我們能夠更輕鬆地開發靜態頁面 (Static Site)、操作體驗良好的單頁式網站 (SPA)、甚至是顧及 SEO 的伺服器端渲染 (SSR) 網站。
Thumbnail
從實際應用中學習 Python 程式設計,提升技能並建立作品集。文章提供八個循序漸進的 Python 專案範例,涵蓋檔案操作、網路爬蟲、Web 應用、自動化腳本、數據分析、遊戲開發、API 互動及應用程式部署,並附上實戰建議及學習資源。
Thumbnail
從實際應用中學習 Python 程式設計,提升技能並建立作品集。文章提供八個循序漸進的 Python 專案範例,涵蓋檔案操作、網路爬蟲、Web 應用、自動化腳本、數據分析、遊戲開發、API 互動及應用程式部署,並附上實戰建議及學習資源。
Thumbnail
這是一場從「網路連結 → 線下見面」的活動,我一開始其實有些猶豫,畢竟地點對我來說不近,加上平常在社群裡其實不太主動互動。 但因為主辦人西打誠意滿滿地邀請,甚至還提出補貼車資,最後我決定自費參加。現在回頭看,真的很值得! 場地很有感,氛圍超溫暖 一踏進場地就被暖黃的燈光包圍,小閣樓超舒適,還
Thumbnail
這是一場從「網路連結 → 線下見面」的活動,我一開始其實有些猶豫,畢竟地點對我來說不近,加上平常在社群裡其實不太主動互動。 但因為主辦人西打誠意滿滿地邀請,甚至還提出補貼車資,最後我決定自費參加。現在回頭看,真的很值得! 場地很有感,氛圍超溫暖 一踏進場地就被暖黃的燈光包圍,小閣樓超舒適,還
Thumbnail
網站開發專案成功的關鍵在於與客戶的有效溝通。本文分享一個成功案例,說明如何透過明確掌握專案需求、主動提供技術方案、定期回報進度、完善技術協助及建立良好客戶關係,順利完成一個中文影片學習分享網站的建置,並獲得客戶高度滿意與後續合作機會。
Thumbnail
網站開發專案成功的關鍵在於與客戶的有效溝通。本文分享一個成功案例,說明如何透過明確掌握專案需求、主動提供技術方案、定期回報進度、完善技術協助及建立良好客戶關係,順利完成一個中文影片學習分享網站的建置,並獲得客戶高度滿意與後續合作機會。
Thumbnail
這是一場修復文化與重建精神的儀式,觀眾不需要完全看懂《遊林驚夢:巧遇Hagay》,但你能感受心與土地團聚的渴望,也不急著在此處釐清或定義什麼,但你的在場感受,就是一條線索,關於如何找著自己的路徑、自己的聲音。
Thumbnail
這是一場修復文化與重建精神的儀式,觀眾不需要完全看懂《遊林驚夢:巧遇Hagay》,但你能感受心與土地團聚的渴望,也不急著在此處釐清或定義什麼,但你的在場感受,就是一條線索,關於如何找著自己的路徑、自己的聲音。
Thumbnail
背景:從冷門配角到市場主線,算力與電力被重新定價   小P從2008進入股市,每一個時期的投資亮點都不同,記得2009蘋果手機剛上市,當時蘋果只要在媒體上提到哪一間供應鏈,隔天股價就有驚人的表現,當時光學鏡頭非常熱門,因為手機第一次搭上鏡頭可以拍照,也造就傳統相機廠的殞落,如今手機已經全面普及,題
Thumbnail
背景:從冷門配角到市場主線,算力與電力被重新定價   小P從2008進入股市,每一個時期的投資亮點都不同,記得2009蘋果手機剛上市,當時蘋果只要在媒體上提到哪一間供應鏈,隔天股價就有驚人的表現,當時光學鏡頭非常熱門,因為手機第一次搭上鏡頭可以拍照,也造就傳統相機廠的殞落,如今手機已經全面普及,題
Thumbnail
本文分析導演巴里・柯斯基(Barrie Kosky)如何運用極簡的舞臺配置,將布萊希特(Bertolt Brecht)的「疏離效果」轉化為視覺奇觀與黑色幽默,探討《三便士歌劇》在當代劇場中的新詮釋,並藉由舞臺、燈光、服裝、音樂等多方面,分析該作如何在保留批判核心的同時,觸及觀眾的觀看位置與人性幽微。
Thumbnail
本文分析導演巴里・柯斯基(Barrie Kosky)如何運用極簡的舞臺配置,將布萊希特(Bertolt Brecht)的「疏離效果」轉化為視覺奇觀與黑色幽默,探討《三便士歌劇》在當代劇場中的新詮釋,並藉由舞臺、燈光、服裝、音樂等多方面,分析該作如何在保留批判核心的同時,觸及觀眾的觀看位置與人性幽微。
追蹤感興趣的內容從 Google News 追蹤更多 vocus 的最新精選內容追蹤 Google News