Liquid、JavaScriptなどに関する質問
新参者です。
的外れな質問になるかも知れませんが、ご教授いただければ幸いです。
※Shopifyサポートに問合せましたが、技術的なことには回答できないとのことでしたので「技術的なQ&A」に投稿しました。
下記の設定項目で、「リダイレクト元」に、ある形式のURLクエリパラメータ(クエリストリング)を設定すると
リダイレクトできません。どのような値を入力すればリダイレクトが実現可能であるかご教授ください。
【設定画面】
ストア管理/オンラインストア/メニュー/URLリダイレクト/URLリダイレクトを作成
【設定項目】
・リダイレクト元 ← ココ
・リダイレクト先
【入力例】
「リダイレクト元」に
/?pid=12345 と 値を入れて「保存する」を実行すると
↓
?pid=12345 という値に自動変換されて登録されます。
「リダイレクト先」には
/products/12345 と 値を入れて「保存する」を実行すると
↓
/products/12345 そのままの値が登録されます。
上記の内容で設定した場合にリダイレクトは実行されませんでした。
推測されるリダイレクトされない原因は、例えばブックマーク等で旧URL
...//hoge.com/?pid=12345 にアクセスしたとします。
しかし、Shopifyのリダイレクト設定でのリダイレクト元は
...//hoge.com?pid=12345
/ なしの形式で待っているようで、ミスマッチとなりリダイレクトが実行されていないようです。
尚、システムの移行は、ドメインの変更はなし(同一ドメイン)で、旧URLはリンク切れ(404 Not Found)の状態になってます。
単純な文字列比較を行ってマッチングを行っているようで、URLエンコード(\)やワイルドカードなど試しましたが
リダイレクトを実現できませんでした。
どのような形式で「リダイレクト元」を設定すればよいのか?または、これを解決するアプリなど
ご存知でしたらご教授いただければと考えております。
以上、宜しくお願い致します
解決済! ベストソリューションを見る。
成功
本筋とずれるかもしれませんので不要なら無視していただきたいのですが、どうやってリダイレクトするかという点の案が作れそうでしたので一応記載したいと思います。
骨子は以下の通りです
該当のコードは以下のものですが、テストできていない上かなり適当なので自信はありません。
スタイルシートやDOMの読み込みを待つ必要はないため早い段階でJSが即実行できればよく、想定している記載箇所はheadの上の方です。
<script>
function getParam(name, url) {
if (!url) url = window.location.href;
name = name.replace(/[\[\]]/g, "\\$&");
var regex = new RegExp("[?&]" + name + "(=([^&#]*)|&|#|$)"),
results = regex.exec(url);
if (!results) return null;
if (!results[2]) return null;
return decodeURIComponent(results[2].replace(/\+/g, " "));
}
function redirect(){
var pid = getParam('pid');
if( pid != null ){
location.href= "https://example.com/products/" + pid;
}
}
redirect();
</script>
参考URL:
http://www-creators.com/archives/4463
意図している動作は以下の通りです。
懸念点は以下の通りです。
未検証かつ無理やりでバッドノウハウな案と言えますので、Shopifyで実際に動いたとしてもお勧めしがたいのですが、最悪JSでどうにかできなくもないかもしれません。
リダイレクト元の入力欄にある説明で、
訪問者を転送したい元のURLです。通常、これは、コンテンツが別のURLに移動されたか削除されたため、訪問者がアクセスできなくなった古いページです。
とあるので試して見たところ、リダイレクト元は存在しないページではないと動かないようでした。
つまり、実際そのページにアクセスして404になるページしか、リダイレクト元に設定できないようです。
/?p=12345 というパスはトップページなので、トップページを404にする方法は、オンラインストアを利用しないプラン(shopify light)にすることだと思うのですが、
そもそもこのリダイレクト機能自体、オンラインストアの機能なので、プラン変えると、リダイレクト自体無効化されると思います。
つまり、オンラインストアのリダイレクト機能でトップページをリダイレクトするとのは(クエリがあっても)無理なのではないでしょうか 😅
アプリを使った代替方法は、申し訳ないですが、ちょっと検討がつかないです 🙇
ご回答ありがとうございます。
なるほど、旧URLである.../hoge.com/?pid=12345のURLクエリパラメータの書式に限って、ShopifyではTOPページを指す書式であり
404にはなりえず、そもそもURLクエリパラメータは、Shopifyでは無効な書式であり無視される扱いということでしょうか。
なので、設定画面での保存時に、URLクエリパラメータの書式のみ明示的に、先頭「/」を消去する
書式変換処理(マッチングしない文字列に変換)を行うようにしている
そういう仕様ということで認識あってますか?
何の意図があって、URLクエリパラメータのリダイレクト機能がそういう処理をしているのか
何故、オフィシャルサイトに上記の仕様が明記されてないのか気にはなりますが、
/? で始まる文字列を登録できないのであればどうにもなりません。
TOPページURLにURLクエリパラメータのみを付随させたページ表現は、他のECやCMSでは頻繁に利用されている書式なので
こういったサイトからの移行で、恒久リダイレクトのSEO的な恩恵はShopifyでは諦める他ないのでしょうね。
しばらく、1週間ほど他のレスポンスも待ってみます。
それで何も進展がないようでしたら、ベストソリューションとさせていただきます。
以上、宜しくお願い致します
すいません、
> なるほど、旧URLである.../hoge.com/?pid=12345のURLクエリパラメータの書式に限って、ShopifyではTOPページを指す書式であり
ここでおっしゃってる旧URLとは、 ドメインを変更されたということですか?
そもそもこの設定は、相対パスでしかできないので、現状のShopifyストア内でのリダイレクトのみ有効です。
そしてShopifyのURL構成は全てパスで表現されて、クエリパラメータは使っていないので、リダイレクトの設定にクエリパラメータは不要かと思います。
また、クエリパラメータをのぞいて、「/」 で登録しようとするとエラーとなりますが、これは現状のストアのTOPが存在せず、かつそれを現状のストアのどこかにリダイレクトすることになり、矛盾するからだと思います。
なお、/?pid=12345 も、?pid=12345 もアクセスするURLとしては同様に処理されますので、「/」が消されることは直接事象とは関係ないと思われます。
上記の方がおっしゃるように、設定画面に、削除されたページのみリダイレクトすると書いてあるので、単純にTOPは存在しているのでリダイレクトされないのだと思います。
(そういう意味で、クエリパラメータのみの設定も本来エラーとして設定できない方が良い気もしますが。。)
ご回答ありがとうございます。
>> なるほど、旧URLである.../hoge.com/?pid=12345のURLクエリパラメータの書式に限って、ShopifyではTOPページを指す書式であり
> ここでおっしゃってる旧URLとは、 ドメインを変更されたということですか?
いいえ、ドメインは変更しておりません。(既にDNSでドメインはShopifyへ向けられ関連付けされてます)
他のECからShopifyへシステムを移行した場合の質問で、URLで変わるのはドメインより下方の文字列になります。
例)
旧商品URL ..://hoge.com/?pid=1234
新商品URL ..://hoge.com/products/1234
また、Shopifyがクエリパラメータ形式を採用していないことは承知しております。
> なお、/?pid=12345 も、?pid=12345 もアクセスするURLとしては同様に処理されますので、「/」が消されることは直接事象とは関係ないと思われます。
もし同様に解釈されるのであれば、「?pid=1234」の設定でリダイレクトできているかと思います。
ブラウザは自動的に「?」の前に「/」を追加補完し表現はしますが、Shopifyのリダイレクトは、あくまで「?pid=1234」という文字列で比較しているものと考えられます。
というのもですね、QAにあげる前に行った検証では
「?pid=1234」から「?」を抜いて「「/pid=1234」」と登録すると「..://hoge.com/pid=1234」でアクセスしてリダイレクトされます。
他に「?」を「&」などに変えても「..://hoge.com/&pid=1234」でアクセスしてリダイレクトされます。
でしたので、皆さまからご教授しただいている
TOPページや相対パスなどのシステムの作用はうけておらず単純に文字列を比較しているものと解釈しております。
また、適当なURL
例) .://hoge.com/&&&&hogehogehoge
などでも、リダイレクト元に「/&&&&hogehogehoge」と記述すれば、元々あったURLか否かも関係なく
同一ドメイン上で存在しないURLはリダイレクトされます。
上記のことから、私が知りたいことは
なぜ、「/?」から始まるURLクエリパラメータの書式に限って「/」を登録後に削除する挙動をするのか?
挙動の理由は不明であれ、「/?」から始まるURLクエリパラメータの書式とイコールとなる入力表現方法はないのか?
となります。
これはいたずらなのでしょうか??。。。それともよほどの理由でもあるのでしょうか。。
またまた長文になり申し訳ありません。
以上、宜しくお願い致します
詳細を共有いただきありがとうございます。
内容は理解いたしました。
> 「?pid=1234」から「?」を抜いて「「/pid=1234」」と登録すると「..://hoge.com/pid=1234」でアクセスしてリダイレクトされます。
> 他に「?」を「&」などに変えても「..://hoge.com/&pid=1234」でアクセスしてリダイレクトされます。
HTMLの仕様上、最初の? を抜かすして / を入れるとそれ以降パスとみなされるので、この状況でリダイレクトされるのは、
>また、適当なURL
> 例) .://hoge.com/&&&&hogehogehoge
> などでも、リダイレクト元に「/&&&&hogehogehoge」と記述すれば、元々あったURLか否かも関係なく
> 同一ドメイン上で存在しないURLはリダイレクトされます。
こちらの状況と全く同じですので、不思議な点はないかと思います。
試しに、登録なしで
hoge.com/pid=1234 や、 hoge.com/&pid=1234 にアクセスすると 404 となります。
ですので、
> ブラウザは自動的に「?」の前に「/」を追加補完し表現はしますが、Shopifyのリダイレクトは、あくまで「?pid=1234」という文字列で比較しているものと考えられます。
こちらは誤りで、
> なぜ、「/?」から始まるURLクエリパラメータの書式に限って「/」を登録後に削除する挙動をするのか?
/ を入れても入れなくても、 HTTPの正しい規約(RFCの正しい仕様は、そのURLが一意の場所を示す場合、最後のスラッシュは入れないので(入れるとディレクトリを指しますので、その後にファイル名が続くことを期待されます。))に対応するために、Shopifyが変換しているのだと思います。
普通のレンタルサーバーなどでは、ROOT配下に、index.htmlなどを置くため、 / -> /index.html に補完されて表示されますが、Shopifyはクラウドサービスですので、基本的に、/ で終わるURLを提供するのは本来、HTTPの仕様上は間違っております。
以下にご説明があるので、ご参考ください。
https://pr.toriaez.jp/navi/column/404.html
ですので、ご共有いただいている挙動は特に不思議な点はない認識です。
ただし、移行前の元のショップが、/?pid=1234 で特定商品を表していて、それをShopify移行後のリダイレクトに設定できない不便さは理解いたします。。
(前述の通り、hoge.com/?pid=1234 というのは、厳密にはURLの記述としては間違いなので、元々のサイトが、 hoge.com?pid=1234 か、hoge.com/index.html?pid=12334であれば問題なかったと申し上げるしかないのですが。。)
すいません、
> hoge.com?pid=1234 か、hoge.com/index.html?pid=12334であれば問題なかったと申し上げるしかないのですが。。
hoge.com?pid=1234 だと、404にならないので、hoge.com/index.html?pid=12334 (またはそれに準じるトップファイルの記述)しか有効でないですね。。
ご返答ありがとうございます。
なるほど、URLの終末/より後の値をファイルとするHTTPルールですか
URLクエリパラメータ自体がファイル名ではなく条件なので意識から欠落してました。
また、404にもなってませんね、申し訳ありませんでした。
通常の.htaccessファイルに記述するリダイレクト処理と同様に文字列の比較
をしているものだという固定観念もありました。
HTTPルールが働いているとすると
「/?pid=1234..」形式で始まる文字列が登録されたらURLクエリパラメータ(ファイルでもない)と
認識して、URLクエリパラメータの開始/をURLの終末/として解釈し削除しているということですかね。
であれば、登録時に「/」以降を全て消すか何らかの警告は欲しいものです。
または、仕様に明記していただきたいですね。
SaaS型の利点も多々ありますが、.htaccessで数行の記述で済む処理なので
このパターンは網羅しておいていただきたいところでした。
理由を追求しても仕様で明記されていないので、この辺でクローズしたいと思います。
動作に関しましても、管理画面のカスタマイズは不可ですので仕様が網羅する方向に動くまで
挙動に従う他ないと認識します。
ご親切に新参者にお付き合いいただきました皆さまに感謝いたします。
ありがとうございました。
以上、宜しくお願い致します
成功
本筋とずれるかもしれませんので不要なら無視していただきたいのですが、どうやってリダイレクトするかという点の案が作れそうでしたので一応記載したいと思います。
骨子は以下の通りです
該当のコードは以下のものですが、テストできていない上かなり適当なので自信はありません。
スタイルシートやDOMの読み込みを待つ必要はないため早い段階でJSが即実行できればよく、想定している記載箇所はheadの上の方です。
<script>
function getParam(name, url) {
if (!url) url = window.location.href;
name = name.replace(/[\[\]]/g, "\\$&");
var regex = new RegExp("[?&]" + name + "(=([^&#]*)|&|#|$)"),
results = regex.exec(url);
if (!results) return null;
if (!results[2]) return null;
return decodeURIComponent(results[2].replace(/\+/g, " "));
}
function redirect(){
var pid = getParam('pid');
if( pid != null ){
location.href= "https://example.com/products/" + pid;
}
}
redirect();
</script>
参考URL:
http://www-creators.com/archives/4463
意図している動作は以下の通りです。
懸念点は以下の通りです。
未検証かつ無理やりでバッドノウハウな案と言えますので、Shopifyで実際に動いたとしてもお勧めしがたいのですが、最悪JSでどうにかできなくもないかもしれません。
jizo 様
毎度、ご返答いただきありがとうございます。
また、解決案のご教授に感謝いたします。
リダイレクト先のパターンは一定ですので、複数パターンを記述する必要はなさそうです。
ただ、JavaScriptですよね、これってShopify Plusでなくても追加できますかね?
規模がShopify Plusまでないので、その辺も踏まえて専任者にこの案を伝えて意見を
仰ぎたいと考えております。
結果がで次第、投稿いたします。
以上、宜しくお願い致します
ご回答ありがとうございます。
> ただ、JavaScriptですよね、これってShopify Plusでなくても追加できますかね?
はい、動作します。Shopifyのストアフロントのテンプレート(テーマ)はファイルの一式でして、ダウンロードしてローカルで編集してアップロードして使うこともできますので、内容は自由に変更可能です。
(ただし、配送住所から決済までのチェックアウトフローの部分は、おっしゃっているPlusプランでしかできません)。
ファイルはダウンロードしなくても、オンラインストア>テーマ>テーマのコード編集 から管理画面上で直接いじることができます。
template.liquid というファイルが全ての画面で呼ばれるフレームみたいなものなので、そこの<head> 内などに、上記でご提示されているコードを入れれば、上記のチェックアウトフロー以外全てで読み込まれますし、index.liquid などに入れれば、TOP画面でのみ読み込まれます。
assets/ ディレクトにJSファイルを作って、それを<script>タグで読み込ませることなども自由に可能ですのでお試しください。
元々、.htaccess で制御されているのであれば、.htaccess 自体は動作しないですが、それに準拠したJSを挿入することは可能です。
ご返答ありがとうございます。
なるほどなるほど、Shopifyのからくりについて学習することは、今日において英語力のない
私にとっては厳しいのが現実ですので大変助かります。
そろそろエンジニア目線での日本語による良書が出てくれないものですかね、、、
実際にShopify Plus に至らないプランにより、決済関連で手の施しようがなく難儀しました。
ご教授いただいた内容をもとに課題解決に向かいます。
結果がでましたら投稿させていただきます。
以上、宜しくお願い致します
ご連絡ありがとうございます。
日本語の技術情報については、完全な翻訳ではないですが、以下の開発者向けブログと
https://www.shopify.jp/blog/partner-shopify-app-development
それを基にした解説動画をご覧いただければと思います。
https://www.youtube.com/playlist?list=PLkR3LRtxAZfod8TvcsKU7IEWeAO5fhcOe
他の日本語の技術情報は「開発」タグでまとまっております。
https://www.shopify.jp/blog/topics/%E9%96%8B%E7%99%BA
このフォーラム内に、日本のサポートチームが作成したFAQ(「よくあるお問い合わせ」とついているもです)もありますので、合わせてご覧ください。
https://community.shopify.com/c/Shopify-Community-Japan/ct-p/jp
ご返答ありがとうございます。
開発の栞をご提示いただき大変助かります。
これをもとに、Shopifyへのアプローチの可否を見極めつつ
探索してみたいと考えております。
ありがとうございました。
以上、宜しくお願い致します
jizo 様
連絡がございます。
既に本課題を抱えているサイトは稼働を開始しており、また課題解決に時間を要していることもあり
恒久リダイレクトの期待値が下がってきておりました。
ご提示いただいた解決策を踏まえ、メリデメを吟味いたしましたところ
恒久リダイレクトは見送ることとなりました。
それにより、ご提供いただいたプログラムを活かすことができなくなりました。
大変申し訳ございません。
ご提供いただいたJSプログラムに関しましては、URLパターンに対して動的に動作するものと解釈しており
htaccessのRewriteRule/RewriteCond 形式でイメージしておりました処理を完全に網羅するもので
十二分に活用できる代物と期待しておりました。
検証および活用に至らず、重ねてお詫びいたします。
余談ですが、私のイメージは↓になります。ほぼビンゴなJSのご提供かと思われます。
変換前URL : ttps://hoge.com/?pid=1234
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{QUERY_STRING} ^pid=(.*)$ [NC]
RewriteRule .* ttps://hoge.com/products/%1? [R=301,L]
</IfModule>
変換後URL : ttps://hoge.com/products/1234
このスレッドの扱いに関しましては、実態と考察とまではいきませんが
後日、タイムスタンプ付き(YYYY/MMDD時点と明記)でのまとめ投稿をし
クローズする方向で考えております。
以上、宜しくお願い致します
状況その他お知らせいただきありがとうございます。
また、試作したコードを利用しないとなりましてもまったく問題ありませんので、その点はお気になさらずお願できればと思います。
お気遣いいただきありがとうございます。
契機は当方の都合によるものですが、考察の末、一定の結果は得ることができたと判断しましたので
以下にまとめとして記述しクローズいたします。
【質問内容】
設定画面:ストア管理/オンラインストア/メニュー/URLリダイレクト/URLリダイレクトを作成/
のリダイレクト元項目にURLクエリパラメータ形式で値を入力し保存すると入力値が自動変換され
結果的にリダイレクトできない。
そこで「/?」から始まるURLクエリパラメータ形式をどのように設定すればリダイレクトできるのか知りたい。
実例)
-- 入力時
/?pid=1234 → ?pid=1234 と 先頭「/」が消去される
-- 実行時 アクセスURLと比較URL
ttps://hoge.com/?pid=1234 =不一致= ttps://hoge.com?pid=1234
※ドメイン変更なしで他ECからShopifyへシステムを移行したパターン
【結果】
様々なご意見をいただきましたが、設定画面からの設定方法において直接的な解決には至っておらず
故に、URLクエリパラメータ形式をリダイレクト元へ設定することは、現時点で不可です。
-- 2020/09/05 時点
【代替案】
JavaScriptにより、アクセスされたURLを解析し、URLクエリパラメータ形式である場合に恒久リダイレクトする
.htaccessにおける動的な処理
RewriteCond %{QUERY_STRING} ^pid=(.*)$ [NC]
RewriteRule .* ttps://hoge.com/products/%1? [R=301,L]
jizo 様よりJavaScriptのサンプルソースをいただいておりますので、参考にされてください。
https://community.shopify.com/c/%E6%8A%80%E8%A1%93%E7%9A%84%E3%81%AAQ-A/URL%E3%82%AF%E3%82%A8%E3%83%...
【考察】
本課題では、この設定画面における一連の挙動についての公式なソースは存在しないため
これが、非公開の仕様なのか、未だ実装中なのか、はたまたバグの放置なのか困惑することになり
腰を据えた開発(プライベートアプリなど)を選定する妨げとなりました。
不確実性の高いものにアプローチするリスクは避けるべきことなので、公式な仕様公開に期待します。
以上、宜しくお願い致します
Shopify アカデミーの学習パスと認定スキルバッジExpanding Your Shopify Business Internationallyを活用して、国際的にビジネ...
By Shopify Feb 7, 2025Shopify アカデミーの学習パスB2B on Shopify:立ち上げとカスタマイズで卸売販売に進出しましょう。これら3つの無料コースは、ShopifyストアでB2B機能...
By Shopify Jan 31, 2025サポートの選択肢が増えていく中、最適となる選択の判断が難しくなっているかと存じます。今回は問題の解決に最適となるサポートの選択方法を、紹介させて頂きます。 選択肢のご紹介...
By Mirai Oct 6, 2024