昨天每張專輯都有了自己的網址。今天換一個情境。
我在專輯列表搜尋「NewJeans」,再把年份篩成 2024,終於只剩下她們那一年發行的兩張專輯。結果一按重新整理——條件全部消失,又回到完整列表。 或是換一個情境:我想把這組結果傳給朋友,複製現在的網址跟他說「你看這幾張」。結果他打開之後,看到的還是沒有搜尋、沒有篩選的完整列表。
【圖 1|搜尋加篩選之後,網址完全沒變】
還有昨天留下來的那一個:點了 Superbeing 版,畫面換了,但網址還停在專輯本身。

【圖 2、3|切換版本,網址也沒變】
這幾件事的共同點是:畫面上發生的事情,網址完全不知道。
今天,就來讓網址也記得這些事情。
昨天拆鐵人賽的網址時,有一段刻意先跳過了:
https://ithelp.ithome.com.tw/2026ironman/signup/list?group=vibe-coding
昨天處理的是中間的路徑:
/2026ironman/signup/list
今天要看的是最後這段:
?group=vibe-coding
它的意思是「在報名列表裡,只看 Vibe Coding 組」。
如果把昨天的路徑想成地址,參數就很像地址後面附的一張備註。地址決定你去哪裡;備註補充的是:到了之後,我想怎麼看。
拿這個網址來說:
地址:去鐵人賽的報名列表
備註:只看 Vibe Coding 組
試著把 ?group=vibe-coding 刪掉再打開,你還是會在報名列表,只是變回所有組別都顯示。
在這個例子裡,把備註撕掉之後,主要的目的地沒有變,只是少了一個條件。
所以可以先用這個方法判斷:拿掉之後,如果還是同一個主要內容、只是少了一個條件,通常比較適合放參數;如果連主要對象都變了,通常比較像路徑。
這只是一個好用的判斷方式,不是 Web 的硬規則——第三節會看到不同網站其實有不同選擇。
先看剛剛那一個:
? group = vibe-coding
└名稱┘ └─── 值 ───┘
?:從這裡開始是參數group:參數的名稱vibe-coding:參數的值如果不只一個,就用 & 接下去。例如在 Google 搜尋:
https://www.google.com/search?q=iphone&hl=zh-TW
可以讀成:
q=iphone 搜尋 iphone
hl=zh-TW 介面用繁體中文
同一個搜尋頁,帶了兩個條件。& 讀作「而且」就好。
另外,如果你在 Google 搜尋「耳機」,有時候複製出網址會看到:
?q=%E8%80%B3%E6%A9%9F
瀏覽器可能還是把網址顯示成中文,但在網址實際傳遞時,中文和部分特殊字元會經過 URL encoding,所以才會出現 %E8... 這種形式。這不是壞掉,只是網址表示文字的一種方式。
#你可能也看過網址裡有 #,例如維基百科:
https://en.wikipedia.org/wiki/K-pop#History
它叫片段,用來跳到頁面裡的某個位置——打開這個網址,會直接捲到「History」那一節。
它跟參數最大的差別是:# 後面的東西不會送到伺服器,只有瀏覽器自己知道。
用地址來說,它像是信封角落寫著「給二樓的小明」:郵差只負責把信送到這個門牌,至於要拿給屋裡的誰,是家裡的人收到信之後自己處理的——郵差根本不看這行字。
今天不會用到它,知道它不是參數就好。
在動手之前,先把今天真正的問題問清楚。
搜尋條件、篩選、目前看的版本、收藏⋯⋯這些東西都要「被記住」。但它們能被記住的地方有好幾個,而且各自解決的問題不一樣:
| 放在哪裡 | 主要解決什麼 | 例子 |
|---|---|---|
| 畫面裡 | 這一刻畫面怎麼顯示 | 下拉選單有沒有展開 |
| 網址 | 這個畫面怎麼被還原、被分享 | 搜尋、篩選、版本 |
| 這台瀏覽器 | 這台裝置下次還記得什麼 | 深色模式、目前的收藏 |
| 資料庫 | 系統或帳號真正保存了什麼 | 之後的收藏、投稿、帳號資料 |
這四個不是一條「越來越永久」的路,而是不同用途的位置。所以要決定放哪裡,其實是在回答兩個不同的問題。
重新整理之後,希望還原成同一個畫面嗎?把網址傳給別人時,希望他看到一樣的結果嗎?
兩題的答案都是「希望」,這個狀態就很適合放進網址。
搜尋和篩選就是典型的例子:
/albums?q=newjeans&year=2024
重新整理不會消失,複製給朋友,他也能看到同一組結果。
另一個問題完全不同:
這個東西本身,要不要被長期記住?而且跟著某個使用者,到哪台裝置都在?
這時候才是在決定要不要存進瀏覽器,或是資料庫。
例如「我收藏了哪幾張專輯」,它不是一個畫面的條件,而是使用者自己的資料。現在它存在這台瀏覽器裡,換一台裝置就沒了;如果希望登入之後到哪裡都看得到,就得存進資料庫——那是第三幕的事。
網址記的是「現在怎麼看」;資料庫記的是「真的有哪些資料」。
這兩件事不是二選一。以收藏來說,之後很可能會同時用到兩個地方:
/favorites?type=studio-album
一個負責東西本身,一個負責怎麼看它。
很適合放:搜尋關鍵字、篩選條件、排序方式、第幾頁、目前看的版本。共同點是——重新整理或把網址交給別人時,通常希望看到同一個狀態。
通常不用放:很短暫的 UI 狀態,例如滑鼠正在 Hover 哪張卡片、下拉選單此刻有沒有展開、按鈕正在 Loading。除非產品真的有「直接還原這個狀態」的需求,否則沒必要讓網址也記住。
不該放敏感資訊:密碼、登入權杖、私密個資等。網址可能出現在瀏覽紀錄、伺服器紀錄,也很容易被複製或分享出去,所以不能把它當成秘密空間。
至於昨天的 Drawer,也不需要再另外加一個 drawer=open。現在「哪張專輯被打開」已經由 /albums/[slug] 表示,同一件事沒必要記兩次。
講完規則,要老實說一句:路徑和參數的界線,各家做法都不一樣。
看 Apple 官網的搜尋:
https://www.apple.com/tw/search/iphone?src=globalnav
└關鍵字┘

【圖 4|Apple 官網將搜尋的關鍵字放在路徑中】
Apple 把搜尋關鍵字放進路徑;Google 搜尋則常用 ?q=iphone。YouTube 一般影片網址會看到 ?v=xxxx,Shorts 又使用 /shorts/xxxx。
相近的需求,不同產品也可能做出不同的 URL 設計。
所以與其背「什麼一定要放哪裡」,不如先問兩件事:
這個專案裡,我選擇把搜尋和篩選放進參數:它們不是一個需要獨立網址的主要內容,而且關鍵字、年份、類型、排序都可能自由組合。
回頭看 Apple 那個網址的後半段:
?src=globalnav
它沒有改變這次搜尋結果,比較像是一個來源標記:記錄這次操作是從哪個入口發生的。
網站常會用這類參數做分析,例如比較使用者從不同入口、活動或廣告進站之後的行為。你常看到的 utm_source=... 也是類似用途,之後有機會講數據分析或流量來源時還會再遇到。
所以參數其實有兩種用途:一種會改變你看到什麼,一種只是附帶記錄一些資訊。 今天要做的都是前者。
先從昨天留下來的那個開始,因為它最單純。
現在在《Armageddon》的詳情頁切到 Superbeing 版,畫面換了,但只要按重新整理,就會跑回預設的版本。版本這件事,目前只活在畫面裡。
用第二節的兩個問題來看:重新整理之後,希望還是 Superbeing 嗎?希望。把網址傳給朋友時,希望他直接看到 Superbeing 嗎?也希望。所以版本很適合被寫進網址。
至於換一台裝置之後要不要「記得我上次看的是哪個版本」,那是另一個問題,跟今天要做的 URL state 不一樣。
那要放路徑還是參數?用第一節的方法,把它撕掉看看:拿掉版本,還是同一張專輯,只是回到預設版本。目的地沒變,所以是備註,我選擇放參數。
如果選擇放到參數,網址可能會變這樣:
/albums/aespa-armageddon?version=superbeing
參數名稱是網站自己定的。version、ver、v 對瀏覽器來說都只是名稱。
這裡的取捨比較像:要短,還是要一眼看懂?
這個專案中我選擇用 version,因為比起少幾個字,我更希望看到網址的人馬上知道它代表什麼。
真正重要的是:整個產品要用同一套命名。 如果這件事有要求,就應該寫進 prompt,而不是每次讓 AI 自己選。
網址變了,不一定會留下一筆瀏覽紀錄。瀏覽器的上一頁,其實是在翻一疊紀錄:你每到一個網址,它就在最上面疊一張;按上一頁,就是往回翻一張。
而改網址的時候,有兩種方式:新增一筆紀錄,疊上一張新的,按上一頁會回到剛剛的網址;或是替換目前這一筆紀錄,把最上面那張換掉,網址列一樣會變,但按上一頁會直接回到更早之前的那一頁。
類似的情況常出現在登入後的跳轉:有些網站會選擇替換掉那一筆紀錄,避免使用者按上一頁又回到登入畫面。
所以這裡有一個畫面上看不出來、但要自己決定的地方:切換版本時,要新增一筆,還是替換目前這一筆?
| 做法 | 切了五個版本之後按上一頁 |
|---|---|
| 每切一次就留一筆 | 要按五次,才回得到列表 |
| 只替換目前這一筆 | 按一次就回到列表 |
兩種在畫面上完全一樣,只有按上一頁才會發現差別。版本切換我選後者——使用者會把「切版本」當成同一頁裡的查看狀態,而不是一次新的瀏覽。
這也是一個很典型的「看起來能跑,但操作起來才知道對不對」的地方。
它們常常一起出現,所以很容易混在一起,但問的問題不一樣:
| 在問什麼 | 例子 | |
|---|---|---|
| 搜尋 | 我要找什麼? | ?q=aespa |
| 篩選 | 這一堆裡面,我只想看哪些? | ?type=studio-album&year=2024 |
搜尋是拿一段文字去比對;篩選是資料本來都在,只是把不符合的先收起來。介面上可以擺在一起,但背後是兩件事。
目標是讓它們都寫進網址:
/albums?q=newjeans&year=2024&sort=newest
參數的名稱和值,我都統一用英文。理由跟 Day 9 定 slug 一樣:中文會被編碼成一長串 %E8...,複製出去不好讀,也不好除錯。(使用者輸入的搜尋關鍵字當然可以是中文,那是他的內容;但像 type、sort 這些由網站定義的值,就用英文。)
前面決定的事情,現在整理成 prompt。我分兩輪做。
以下是我給 Codex 的提示詞:
目前專輯詳情頁的版本切換只存在畫面上,重新整理就消失。請把它同步到網址參數:
- 網址格式
/albums/[slug]?version=...- 切換版本時網址跟著更新,但頁面不要整個重新載入,也不要新增瀏覽紀錄(替換目前這一筆就好)
- 直接打開帶 version 的網址時,顯示對應的版本
- version 不存在時,回到預設版本並把該參數移除
- 不要改動
/albums/[slug]的路由結構- 只保留版本這個參數,不要把其他參數帶進來
- 這一輪先不要處理搜尋、類型、年份
- 不要自行更改參數名稱;如果需要新的網址規則,先提出來讓我確認
開始修改前,先說明你的實作方式和預計修改哪些檔案。或是說你在這方面有更好的建議、有需要我做決定的部分,也可以跟我說。
重點不是 prompt 寫得多漂亮,而是先把這一輪要改的範圍縮小——版本做完、確認能動,再處理列表。出問題的時候,也比較容易知道是哪一步壞的。
以下是我給 Codex 的提示詞:
接著幫我把專輯列表的搜尋與篩選同步到網址參數:
- 關鍵字用
q、年份用year、類型用type、排序用sort- 頁面載入時,要從網址還原目前的搜尋與篩選條件
- 搜尋文字可以即時更新結果與網址,但打字過程使用 replace,不要讓每個字都新增一筆瀏覽紀錄
- 年份、類型、排序等明確的篩選操作使用 push,讓上一頁可以回到上一組條件
- 清除某個條件時,對應的參數也要從網址移除;全部清除後回到乾淨的
/albums- 搜尋不到結果時顯示空狀態,並提供「清除篩選」
- 從列表點進專輯時,不要把只屬於列表的搜尋與篩選參數帶到詳情頁
- 不要把捲動位置、動畫、Hover 等暫時 UI state 放進網址
- 保留目前的列表版面,不要順便重做
- 不要自行更改既有參數名稱;如果需要新的網址規則,先提出來讓我確認
開始修改前,先說明你的實作方式和預計修改哪些檔案。或是說你在這方面有更好的建議、有需要我做決定的部分,也可以跟我說。
「不要順便重做版面」是經驗談:這一輪處理的是網址,不是版面。不講清楚的話,AI 有機會順手把整個列表重畫一次。
| 測什麼 | 應該要 |
|---|---|
| 網址可以記錄所查看的版本 | 網址隨版本改變 |
| 在詳情頁切換版本後重新整理 | 還停在同一個版本 |
| 連續切換幾個版本後按上一頁 | 直接回到列表,不是一個一個版本倒退 |
| 搜尋加篩選之後按重新整理 | 條件還在,結果一樣 |
| 複製網址貼到無痕視窗 | 看到一樣的結果 |
| 按上一頁 | 回到上一組條件,不是離開網站 |
| 清除全部篩選 | 網址也跟著變乾淨 |
| 搜尋一個不存在的關鍵字 | 出現空狀態,而且有清除的按鈕 |


【圖 5、6|版本參數有確實寫入】

【圖 7|將含版本參數的網址輸入到新的無痕視窗,會進入詳情頁且對應版本參數】

【圖 8|搜尋、篩選時,條件也確實寫入網址。將網址放入無痕視窗,可還原搜尋/篩選結果】
今天做的兩件事,在別的產品上也到處都是。
同一個東西的不同看法,就像手機的版本可以長得像下面這樣:
/products/iphone-17?color=black&storage=256
還是同一台 iPhone,只是現在看的是黑色、256GB。
列表上的條件,就像搜尋和篩選,在各個領域可能會長這樣:
電商 /products?q=iphone&brand=apple&sort=price
後台 /orders?status=pending&from=2026-09-01
訂房 /hotels?city=tokyo&guests=2
地址都沒換,只是附上了一張備註。
判斷方式也都一樣:你會不會想把這個畫面傳給別人看?
會的話,那些條件就很值得考慮放進網址。不然你只能跟他說「你自己篩一下,先選待處理,再把日期調到九月」。
今天做的事,其實是把「畫面上發生的事」寫回網址裡。在那之前,你的操作只有自己知道;現在你可以把整個結果交給別人——一個網址,就是一份可以傳遞的畫面。
但有另一種東西,今天沒有解決:「我收藏了哪些專輯」這份資料,現在還只存在這台瀏覽器裡。
收藏頁當然可以有自己的網址,例如 /favorites;但「我到底收藏了哪些專輯」不能只靠網址保存,也不該只活在這台電腦上。搜尋條件適合跟著網址走;個人的收藏資料,則更適合跟著「人」走。 要做到這件事,就會需要帳號和資料庫——那是第三幕的事。
之前有提到,開發者工具可以模擬不同螢幕尺寸,也能幫忙測一些裝置條件,但它終究不等於真機。有一些操作,像是真正用手指操作、呼叫手機鍵盤、在不同瀏覽器與實際裝置上使用,還是可能冒出電腦上沒看到的問題。
明天我們會來解決這件事,我們會換一個角度:把網站放到真的手機上看。 真的拿手機來試一次。
我們明天見。