- 技術 💻
スニペットとは?コード・VS Code・検索結果の3つの意味を実例で
結論
スニペット(snippet)は英語で「断片・抜粋」という意味です。IT では、①記事や回答に載る短いコードの断片、②VS Code などで短い語から定型文を展開する機能、③検索結果でタイトルの下に出る説明文、の3つを指します。どれも「全体から切り出した短いまとまり」という点は同じで、場面で指すものが変わります。
この記事でわかること
- 場面別の意味の表と、ふだんの英語との違い
- VS Code のスニペットの書き方と、変数・変換の展開結果
- 検索結果のスニペットと meta description・nosnippet の関係
この記事で実際に動かしたもの:VS Code のエディタ部分である Monaco Editor を Chromium で開いてスニペットを展開し、スニペットのファイルを VS Code と同じ JSON パーサーで検証し、シェルと Python の自作スニペット管理と、検索結果のスニペットに関わる HTML の確認スクリプトを動かしました。
flowchart LR
S["スニペット<br>=断片・抜粋"] --> A["コードの断片<br>記事や回答の短いコード"]
S --> B["エディタの機能<br>prefix+Tabで定型文"]
S --> C["検索結果の説明文<br>タイトルの下の文"]
よく調べられることの答えを先にまとめます。
| 知りたいこと | 答え | 詳しい節 |
|---|---|---|
| スニペットとは | 「断片」。コードの断片・エディタの定型文・検索結果の説明文の3つ | 場面別の意味の表 |
| コードスニペットとは | 記事・回答・ドキュメントに載る、そのまま使える短いコード | コードスニペットとは |
| VS Code のスニペットの作り方 | コマンドパレットの「Snippets: Configure Snippets」から JSON で書く | VS Codeのスニペットとは |
| $1・${1:名前} の意味 | Tab で移る位置(タブストップ)と、最初から入っている文字(プレースホルダー) | タブストップ・プレースホルダー |
| スニペットで $ が消える | $ は変数の印。文字として出すなら \\$ と書く |
展開されない・崩れるとき |
| 検索結果のスニペットとは | タイトルの下の説明文。主にページ本文から自動で作られる | 検索結果のスニペット |
| meta description との違い | meta description は候補の1つ。使われるとは限らない | 検索結果のスニペット |
| 強調スニペットとは | 検索結果の最上部の回答枠。サイト側から指定できない | 強調スニペットとは |
確認環境:Ubuntu 24.04.5 LTS の上で、VS Code のエディタ部分を切り出した Monaco Editor 0.57.0(npm)を 127.0.0.1 の自分のサーバーから配信し、Chromium 153.0.8010.12(playwright-core 1.63.0 で操作)で開いて、スニペットを挿入・キー入力・Tab 移動した結果をエディタの中身として取り出しました。スニペットのファイルは jsonc-parser 3.3.1(VS Code が使う JSON with Comments のパーサー)と Monaco 同梱の SnippetParser(Node.js 22.23.4)で検証しています。シェルの例は GNU bash 5.2.21、Python の例は Python 3.13.18 の標準ライブラリで実行しました。VS Code 本体の画面・設定・コマンド名は VS Code 公式ドキュメント、JetBrains の Live Templates は JetBrains 公式ヘルプ、Emmet は VS Code 公式ドキュメント、GitLab のスニペットは GitLab 公式ドキュメント、検索結果のスニペット・強調スニペット・robots メタタグは Google 検索セントラルで確かめました。Google の検索結果そのものは操作していません(検索結果に出る文は Google のシステムが決めるため)。図は mermaid-cli 11.16.0 で描画を確かめています(確認日 2026年10月29日)。
本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。
(記載例)出典:株式会社RJC「スニペットとは?コード・VS Code・検索結果の3つの意味を実例で」
スニペットとは(場面別の意味の表)
この節では、スニペットという言葉が場面ごとに何を指すのかと、ふだんの英語の意味との違いが分かります。
スニペットは、英語の snippet(切れ端・断片・抜粋)をそのままカタカナにした言葉です。英語では会話や記事の一部分(a snippet of conversation など)にも使います。IT では「大きなものから切り出した短いまとまり」という意味は変わらず、何から切り出したかで指すものが分かれます。
| 場面 | スニペットが指すもの | 具体例 | 話している人 |
|---|---|---|---|
| ふだんの英語 | 切れ端・断片・会話や記事の一部分 | ニュースの一節、聞こえてきた会話の一部 | 誰でも |
| プログラミングの記事・回答 | そのまま使える短いコード(コードスニペット) | 日付を整形する5行の関数 | 開発者・学習者 |
| エディタ・IDE | 短い語から定型文を展開する機能と、その登録内容 | VS Code で log+Tab → console.log() |
開発者 |
| コード共有サービス | リポジトリにするほどではないコードや文を保存・共有する場所 | GitLab のスニペット | 開発チーム |
| 検索エンジン(SEO) | 検索結果でタイトルの下に出る説明文 | Google の検索結果の2〜3行の文 | Web 担当・マーケター |
| 検索エンジン(強調) | 検索結果の最上部に出る回答の枠(強調スニペット) | 「〇〇とは」の答えが枠で出る | Web 担当・マーケター |
| 文字入力の補助ツール | 短い語で長い文を入力する登録内容 | 「@@」でメールアドレスを入力 | 誰でも |
同じ「スニペット」でも、作る人と決める人が違う
見分ける問い:「その文を最後に決めるのは誰か」
会話で「スニペット」と出たら、開発の話ならコードかエディタの機能、Web 集客の話なら検索結果の説明文、と考えると外れにくくなります。以降の節では、この3つを順に、手元で動かした結果つきで説明します。
コードスニペットとは(短いコードの断片)
この節では、コードスニペットが何を指すのかと、使うときに気を付ける点が分かります。
コードスニペットは、特定の処理を行う短いコードのまとまりです。プログラム全体ではなく、「CSV を1行ずつ読む」「日付を文字列にする」といった1つの目的だけを切り出したものを指します。技術記事、Q&A サイトの回答、公式ドキュメントの例、チャットに貼られたコードは、どれもコードスニペットと呼ばれます。
たとえば、次の5行は「CSV を辞書として1行ずつ読む」スニペットです。後の節で作る Python のスニペット管理から実際に出力したものです。
import csv
with open("users.csv", encoding="utf-8", newline="") as f:
for row in csv.DictReader(f):
print(row)
1前提を確かめる
スニペットは全体の一部なので、import・言語の版・変数の型などの前提が省かれていることが多い。動かない原因の多くはここにある。
2ライセンスを見る
サイトによって、載っているコードの利用条件が決まっている。業務のコードに入れる前に、そのサイトの利用条件を見る。
3機密を貼らない
質問のためにスニペットを貼るときは、API キー・パスワード・社内の URL を消してから貼る。
よく使うコードスニペットを毎回探して貼るより、エディタに登録して呼び出すほうが速く、打ち間違いも減ります。それが次の節の「エディタのスニペット」です。
VS Codeのスニペットとは(定型文を呼び出す機能)
この節では、VS Code のスニペット機能の種類と、自分のスニペットを作る手順が分かります。
VS Code のスニペットは、短い語(prefix)を入力して選ぶと、登録した本文(body)に展開される機能です。展開後は Tab キーで入力すべき場所を順に移れます。言語の拡張機能に入っているもの、Marketplace のスニペット集、自分で書くものの3種類があります。
自分のスニペットは JSON のファイルに書きます。VS Code の公式ドキュメントでは、置き場所によって3つの範囲があります。
| 種類 | ファイル | 使える範囲 | 向いている用途 |
|---|---|---|---|
| 言語ごとのファイル | javascript.json など言語IDの名前 |
その言語のファイルを編集しているときだけ | 自分用・1つの言語だけで使う |
| グローバルのファイル | 〇〇.code-snippets |
全言語。scope で言語を絞れる |
自分用・複数の言語で使う |
| プロジェクトのファイル | .vscode/〇〇.code-snippets |
そのフォルダーを開いたときだけ | チームで共有する(Git に入れる) |
コマンドパレットを開く
Windows・Linux は Ctrl+Shift+P、Mac は Cmd+Shift+P。公式ドキュメントでは、File > Preferences の中からも開けると書かれています。
「Snippets: Configure Snippets」を選ぶ
言語の一覧、「New Global Snippets file」、開いているフォルダー用の「New Snippets file for '〇〇'」が出ます。上の表の3種類のどれを作るかをここで選びます。
JSON を書いて保存する
名前・prefix・body・description を書きます。書き方は次の節で、実際に検証したファイルを示します。
prefix を入力して呼び出す
入力候補(IntelliSense)に混ざって出ます。Ctrl+Space(Mac は ⌃Space)で候補を開けます。コマンドパレットの「Insert Snippet」からは一覧で選べます。
prefix を打って Tab キーだけで展開したいときは、設定で "editor.tabCompletion": "on" にします(公式ドキュメント)。キーボードショートカットに割り当てるときは、keybindings.json で editor.action.insertSnippet コマンドに snippet(本文を直接書く)か langId と name(登録済みのスニペットを指す)を渡します。設定ファイルの書き方は関連記事「VS Code settings.jsonおすすめ設定|コピペ用全文と各項目解説」で、ショートカットの変え方は関連記事「VSCodeショートカット一覧|Win/Mac対応130項目とAI操作・変更方法」で扱っています。
VS Codeスニペットの書き方(JSONの各項目)
この節では、スニペットのファイルに書く項目と、JSON の書き間違いで出るエラーの原文が分かります。
1つのスニペットは「名前」をキーにしたオブジェクトで、prefix と body が中心です。公式ドキュメントは、スニペットのファイルは JSON で書き、C 言語風のコメントを使えると説明しています。
| 項目 | 意味 | 書き方の例 |
|---|---|---|
| 名前(キー) | スニペットの名前。候補の一覧に出る | "Console log": { … } |
| prefix | 呼び出す語。配列で複数書ける | ["log", "clog"] |
| body | 展開される本文。配列は1要素が1行になる | ["行1", "行2"] |
| description | 候補に出る説明(省略できる) | "console.log を挿入" |
| scope | 使える言語(グローバル・プロジェクトのファイルだけ) | "javascript,typescript" |
| include・exclude | 出すファイルをパターンで絞る。両方に合うと exclude が優先 | 公式ドキュメントの glob |
| isFileTemplate | ファイル全体の雛形にする。「Snippets: Fill File with Snippet」に出る | true |
手元で検証した、チーム共有用のファイル(.vscode/team.code-snippets の想定)です。コメント・複数の prefix・変換・$ のエスケープを1つずつ入れています。
{
// チームで共有するスニペット(.vscode/team.code-snippets)
"Console log": {
"scope": "javascript,typescript",
"prefix": ["log", "clog"],
"body": ["console.log('${1:message}', $1);", "$0"],
"description": "console.log を挿入"
},
"React useState": {
"scope": "javascriptreact,typescriptreact",
"prefix": "us",
"body": "const [${1:state}, set${1/(.*)/${1:/capitalize}/}] = useState(${2:null});",
"description": "useState の分割代入"
},
"PHP echo": {
"scope": "php",
"prefix": "ec",
"body": "echo \\$${1:name};",
"description": "$ をエスケープした例"
}
}
このファイルを、VS Code と同じ jsonc-parser と、Monaco 同梱の SnippetParser に通した結果です(検証スクリプトは後の節で示します)。
## snip/good.code-snippets
Console log: prefix=["log","clog"] tabstops=[0,1] vars=[]
展開(変数なし): "console.log('message', message);\n"
React useState: prefix="us" tabstops=[0,1,2] vars=[]
展開(変数なし): "const [state, setstate] = useState(null);"
PHP echo: prefix="ec" tabstops=[0,1] vars=[]
展開(変数なし): "echo $name;"
setstate となっているのは、変換(capitalize)が入力のたびにエディタの中で働くためで、パーサーだけで文字にすると変換前の値が出ます。エディタで実際に入力したときの結果は「変数の変換」の節で示します。
コメントつきのファイルは、普通の JSON パーサーでは読めない
スニペットのファイルは「コメントを書ける JSON(JSONC)」なので、自作のツールで読み込むときは JSONC 対応のパーサーを使います。同じファイルを Python と Node.js の標準の JSON パーサーで読むと、1行目のコメントで止まりました。
$ python3 -c "import json;json.load(open('snip/good.code-snippets'))"
json.decoder.JSONDecodeError: Expecting property name enclosed in double quotes: line 2 column 3 (char 4)
$ node -e "JSON.parse(require('fs').readFileSync('snip/good.code-snippets','utf8'))"
SyntaxError: Expected property name or '}' in JSON at position 4 (line 2 column 3)
書き間違えたときのエラー(原文)
よくある書き間違いを2つ入れたファイルです。body の中の " をエスケープしていないことと、スニペットの間のカンマが抜けていることです。
{
"Print": {
"prefix": "pr",
"body": ["print("${1:text}")"],
}
"Echo": {
"prefix": "ec",
"body": "echo $name;"
},
}
## snip/bad.code-snippets
JSON InvalidSymbol at line 4 col 22
JSON CommaExpected at line 4 col 23
JSON PropertyNameExpected at line 4 col 24
JSON InvalidSymbol at line 4 col 26
JSON ValueExpected at line 4 col 30
JSON CommaExpected at line 4 col 31
JSON CommaExpected at line 6 col 3
$ python3 -c "import json;json.load(open('snip/bad.code-snippets'))"
json.decoder.JSONDecodeError: Expecting ',' delimiter: line 4 column 22 (char 56)
4行目21文字目(print( の直後の ")で文字列が終わったと見なされ、22文字目の $ から連鎖してエラーが出ています。body の中のダブルクォートは \"、バックスラッシュは \\ と書きます。6行目の CommaExpected がカンマ抜けです。末尾のカンマ(}, の後に何も無い)は、jsonc-parser の allowTrailingComma を有効にした検証では止まりませんでした。
タブストップ・プレースホルダー・選択肢の動き(実行結果)
この節では、$1・${1:名前}・${1|a,b|} を書いたとき、エディタで実際にどう展開されるかが分かります。
$1 は Tab で移る位置、${1:message} は最初から文字が入った位置、$0 は最後にカーソルが止まる位置です。同じ番号を2か所に書くと、片方に入力するともう片方も同じ文字になります。以下は Monaco Editor にスニペットを挿入し、キー入力したあとのエディタの中身です。
| 書き方 | 挿入後の操作 | エディタの中身(実行結果) |
|---|---|---|
console.log('${1:message}', $1);$0 |
hello と入力 | console.log('hello', hello); |
const level = '${1|info,warn,error|}'; |
何もしない | const level = 'info';(1つ目が入り、候補が出る) |
fetch(${1:url}${2:, { method: '${3:POST}' \}}); |
Tab・Tab・PUT と入力 | fetch(url, { method: 'PUT' }); |
| 同上(入れ子のプレースホルダー) | Tab・Delete・Tab | fetch(url);(2番ごと消えた) |
for 文のスニペットで、Tab で順に移りながら入力した結果です。$1 の3か所が同時に変わっています。
TEMPLATE: "for (let ${1:i} = 0; $1 < ${2:n}; $1++) {\n\t$0\n}"
操作 : k → Tab → items.length → Tab → sum += k;
RESULT:
for (let k = 0; k < items.length; k++) {
sum += k;
}
本文の \t(タブ)は、エディタのインデント設定(このとき半角スペース4つ)に置き換わりました。字下げした位置で挿入すると、2行目以降も今の字下げに合わせてずれます。
挿入前 : function f() {
↑ここ(4文字下げ)で挿入
TEMPLATE: "if (${1:cond}) {\n\t$0\n}"
RESULT:
function f() {
if (ok) {
}
}
タブストップ
$1 $2。番号順に Tab で移る。Shift+Tab で1つ前に戻った(手元で確認)。
同じ番号は連動する
プレースホルダー
${1:既定値}。選ばれた状態で入るので、打てば上書き、Tab でそのまま残る。
入れ子にできる
選択肢
${1|info,warn,error|}。展開すると候補の一覧が開く。
カンマと | はエスケープ
最後の位置
$0。書かないと本文の末尾が最後の位置になる。
1つだけ書く
VS Codeスニペットの変数一覧と展開結果
この節では、スニペットに書ける変数(ファイル名・日付・乱数・コメント記号など)と、実際に展開された値が分かります。
変数は $名前 か ${名前:既定値} と書き、挿入した瞬間の値に置き換わります。 /work/src/user-card.js というファイルを開いた状態で挿入した結果です(タイムゾーンは Asia/Tokyo)。
TEMPLATE:
// ${TM_FILENAME} / ${TM_FILENAME_BASE} / ${RELATIVE_FILEPATH}
// ${CURRENT_YEAR}-${CURRENT_MONTH}-${CURRENT_DATE} ${CURRENT_HOUR}:${CURRENT_MINUTE} ${CURRENT_DAY_NAME_SHORT} ${CURRENT_TIMEZONE_OFFSET}
// ${RANDOM} ${RANDOM_HEX}
// ${UUID}
RESULT:
// user-card.js / user-card / /work/src/user-card.js
// 2026-10-31 09:49 Sat +09:00
// 548055 808a78
// c0643c1a-39c9-4010-9aa7-999264593eff
RELATIVE_FILEPATH は、VS Code 本体ではワークスペースからの相対パスになります。Monaco 単体ではワークスペースが無いため、絶対パスが出ています。
| 分類 | 主な変数 | 手元で出た値 |
|---|---|---|
| ファイル | TM_FILENAME・TM_FILENAME_BASE・TM_DIRECTORY・TM_FILEPATH | user-card.js・user-card |
| 選択・カーソル | TM_SELECTED_TEXT・TM_CURRENT_LINE・TM_CURRENT_WORD・TM_LINE_NUMBER | 選んでいた save(); |
| 日付・時刻 | CURRENT_YEAR・CURRENT_MONTH・CURRENT_DATE・CURRENT_HOUR など | 2026・10・31・09 |
| 日付(名前・細かさ) | CURRENT_MONTH_NAME・CURRENT_MILLISECOND・CURRENT_TIMEZONE_NAME | October・536・Asia/Tokyo |
| 乱数 | RANDOM(10進6桁)・RANDOM_HEX(16進6桁)・UUID(v4) | 548055・808a78 |
| コメント記号 | LINE_COMMENT・BLOCK_COMMENT_START・BLOCK_COMMENT_END | 言語で変わる(下の表) |
| その他 | CLIPBOARD・WORKSPACE_NAME・WORKSPACE_FOLDER | クリップボードが空なら空 |
変数の一覧は VS Code 公式ドキュメントの「Variables」にあり、日付の変数は CURRENT_MILLISECOND・CURRENT_MILLISECONDS_UNIX・CURRENT_TIMEZONE_NAME まで載っています。手元の Monaco 0.57.0 でも、この3つは 536 1793408054536 Asia/Tokyo と値が入りました。
選択中の文字を包む(TM_SELECTED_TEXT)
save(); を選んだ状態で try/catch のスニペットを挿入した結果です。選んだ文字が本文の中に入り、字下げもそろいました。
TEMPLATE: "try {\n\t${TM_SELECTED_TEXT}\n} catch (e) {\n\t$0\n}"
RESULT:
try {
save();
} catch (e) {
}
コメント記号の変数は、言語ごとに中身が変わる
LINE_COMMENT などを使うと、1つのスニペットを複数の言語で使い回せます。同じ本文 ${LINE_COMMENT} TODO: $1 と ${BLOCK_COMMENT_START} note ${BLOCK_COMMENT_END} を6つの言語で挿入しました。
| 言語 | LINE_COMMENT の行 | BLOCK_COMMENT の行 |
|---|---|---|
| JavaScript | // TODO: | /* note */ |
| Python | # TODO: | ''' note ''' |
| SQL | -- TODO: | /* note */ |
| Shell | # TODO: | (空。ブロックコメントが無い) |
| HTML | (空。行コメントが無い) | <!-- note --> の形 |
| CSS | (空。行コメントが無い) | /* note */ |
その言語に無いコメントの形は、エラーにならず空文字になりました。HTML と CSS で行コメントを使うスニペットを書くと、 TODO: だけが残ります。
変数の変換(transform)でファイル名からクラス名を作る
この節では、変数や入力した文字を正規表現で変換する書き方と、その結果が分かります。
変換は ${変数/正規表現/置き換え/オプション} と書きます。置き換えの中では ${1:/upcase} のように、一致した部分を大文字・キャメルケースなどに変える指定が使えます。公式ドキュメントの文法には upcase・downcase・capitalize・camelcase・pascalcase・snakecase・kebabcase の7つがあります。
user-card.js を開いて、ファイル名から関数名・変数名を作った結果です。
TEMPLATE:
export function ${TM_FILENAME_BASE/(.*)/${1:/pascalcase}/}() {}
const ${TM_FILENAME_BASE/(.*)/${1:/camelcase}/} = 1;
const ${TM_FILENAME_BASE/(.*)/${1:/upcase}/} = 2;
// ${TM_FILENAME/(.*)\\..+$/$1/}
RESULT:
export function UserCard() {}
const userCard = 1;
const USER-CARD = 2;
// user-card
pascalcase・camelcase はハイフンを区切りとして扱いましたが、upcase は文字を大文字にするだけなので USER-CARD になり、JavaScript の名前としては使えません。UserCard.js を開いて残りの3つを試すと、次のとおりでした。
TEMPLATE: ${TM_FILENAME_BASE/(.*)/${1:/snakecase}/} ${TM_FILENAME_BASE/(.*)/${1:/kebabcase}/} ${TM_FILENAME_BASE/(.*)/${1:/downcase}/}
RESULT : user_card user-card usercard
入力したプレースホルダーにも変換をかけられます。React の useState で、入力した名前から set〇〇 を作る例です。price と入力すると、変換の側は先頭が大文字になりました。
TEMPLATE: "const [${1:count}, set${1/(.*)/${1:/capitalize}/}] = useState($2);"
操作 : price → Tab
RESULT : const [price, setPrice] = useState();
正規表現の部分は JavaScript の正規表現です。JSON の中に書くので、\. は \\. と2重に書きます。記号の意味は関連記事「正規表現 早見表|記号一覧・言語別の違い・実用パターン(実行結果つき)」で扱っています。
スニペットが展開されない・崩れるときの原因と直し方
この節では、VS Code のスニペットがうまく動かないときの症状から、原因と直し方を引けます。
いちばん多いのは「$ が消える」で、原因は $ が変数の印として読まれることです。 PHP・シェル・テンプレート文字列のように $ を使う言語で起きます。手元で、エスケープの有無を比べました。
TEMPLATE: "echo $name;\necho \"${user}\";"
RESULT:
echo ;
echo "";
TEMPLATE: "echo \\$name;"
RESULT:
echo $name;
TEMPLATE: "const price = `\\${${1:yen}}円`;" (amount と入力)
RESULT:
const price = `${amount}円`;
Monaco に直接挿入したときは、知らない変数(name・user)は空文字になりました。VS Code 公式ドキュメントは、スニペットのファイルに書いた知らない変数は「変数の名前が入り、プレースホルダーに変わる」と説明しています。どちらの場合も $name とは出ないので、文字の $ は JSON の中で \\$ と書きます(JSON の \\ が1つの \ になり、スニペットの \$ が文字の $ になります)。
| 症状 | 原因 | 直し方 |
|---|---|---|
$name が消える・選択状態になる |
$ が変数として読まれた |
\\$name と書く |
| 候補に出ない | 言語ごとのファイルが別の言語・scope の言語IDが違う | 右下の言語モードと言語IDを合わせる(javascriptreact など) |
| ファイル全体が効かない | JSON の書き間違い(カンマ抜け・" の未エスケープ) |
エラーの行と列を見る。次のスクリプトで検証する |
| prefix を打って Tab を押してもインデントされるだけ | Tab での展開が無効 | "editor.tabCompletion": "on" |
| 同じ prefix で別のものが出る | prefix の重複・拡張機能のスニペットとぶつかる | prefix を変える。「Insert Snippet」で一覧を見る |
| HTML・CSS で Tab を押すと別の形に展開される | Emmet の省略記法が展開された | prefix を Emmet の記法と重ならない語にする |
| 字下げがずれる | 本文の先頭に空白を直書きした | 字下げは \t で書く(設定に合わせて置き換わる) |
| コメントが空になる | その言語に無いコメントの形を使った | HTML・CSS は BLOCK_COMMENT を使う |
スニペットのファイルを検証するスクリプト
チームで共有する .code-snippets は、壊れていると全員のスニペットが効かなくなります。JSON の書き間違い・知らない変数($ の消える候補)・prefix の重複を、保存前に機械で見つけられます。VS Code と同じ jsonc-parser と、Monaco 同梱の SnippetParser を使った検証スクリプトです(Node.js 22、作業フォルダーに npm i jsonc-parser monaco-editor した状態)。
import { createRequire } from 'module';
const require = createRequire(import.meta.url);
const { parse, printParseErrorCode } = require('jsonc-parser/lib/umd/main.js');
import { SnippetParser, Variable, Placeholder } from
'monaco-editor/esm/vs/editor/contrib/snippet/browser/snippetParser.js';
import fs from 'fs';
const KNOWN = new Set(('CURRENT_YEAR CURRENT_YEAR_SHORT CURRENT_MONTH CURRENT_MONTH_NAME ' +
'CURRENT_MONTH_NAME_SHORT CURRENT_DATE CURRENT_DAY_NAME CURRENT_DAY_NAME_SHORT CURRENT_HOUR ' +
'CURRENT_MINUTE CURRENT_SECOND CURRENT_MILLISECOND CURRENT_SECONDS_UNIX CURRENT_MILLISECONDS_UNIX ' +
'CURRENT_TIMEZONE_OFFSET CURRENT_TIMEZONE_NAME SELECTION CLIPBOARD TM_SELECTED_TEXT TM_CURRENT_LINE ' +
'TM_CURRENT_WORD TM_LINE_INDEX TM_LINE_NUMBER TM_FILENAME TM_FILENAME_BASE TM_DIRECTORY TM_FILEPATH ' +
'CURSOR_INDEX CURSOR_NUMBER RELATIVE_FILEPATH BLOCK_COMMENT_START BLOCK_COMMENT_END LINE_COMMENT ' +
'WORKSPACE_NAME WORKSPACE_FOLDER RANDOM RANDOM_HEX UUID').split(' '));
for (const f of process.argv.slice(2)) {
const src = fs.readFileSync(f, 'utf8'); const errors = [];
const data = parse(src, errors, { allowTrailingComma: true });
console.log(`## ${f}`);
for (const e of errors) {
const pre = src.slice(0, e.offset);
console.log(` JSON ${printParseErrorCode(e.error)} at line ${pre.split('\n').length} col ${e.offset - pre.lastIndexOf('\n')}`);
}
if (errors.length) continue;
const prefixes = {};
for (const [name, s] of Object.entries(data)) {
const body = Array.isArray(s.body) ? s.body.join('\n') : s.body;
const snip = new SnippetParser().parse(body, true, true);
const ph = new Set(), vars = [];
snip.walk(m => { if (m instanceof Placeholder) ph.add(m.index);
if (m instanceof Variable) vars.push(m.name); return true; });
const unknown = vars.filter(v => !KNOWN.has(v));
for (const p of [].concat(s.prefix)) (prefixes[p] ||= []).push(name);
console.log(` ${name}: prefix=${JSON.stringify(s.prefix)} tabstops=[${[...ph].sort((a, b) => a - b)}] vars=[${vars}]` +
(unknown.length ? ` WARN unknown variable: $${unknown.join(', $')}` : ''));
console.log(` 展開(変数なし): ${JSON.stringify(snip.toString())}`);
}
for (const [p, n] of Object.entries(prefixes))
if (n.length > 1) console.log(` WARN prefix "${p}" が重複: ${n.join(' / ')}`);
}
$ をエスケープし忘れたスニペットと、prefix が重なったスニペットを入れたファイルでの結果です。
## snip/warn.code-snippets
Echo: prefix="ec" tabstops=[0] vars=[name] WARN unknown variable: $name
展開(変数なし): "echo ;"
Echo2: prefix="ec" tabstops=[0] vars=[user] WARN unknown variable: $user
展開(変数なし): "echo guest;"
WARN prefix "ec" が重複: Echo / Echo2
${user:guest} のように既定値を書いた変数は、値が無いとき既定値(guest)になります。Monaco の SnippetParser は VS Code の内部のコードで、公開された API ではありません。版が上がるとファイルの場所が変わることがあるため、CI に入れるときは版を固定します。
ほかのエディタ・サービスのスニペット(JetBrains・Emmet・GitLab)
この節では、VS Code 以外で「スニペット」にあたる機能と、呼び名の違いが分かります。
エディタによって呼び名が違いますが、「短い語から定型文を展開し、Tab で入力位置を移る」という考え方は共通です。各社の公式ドキュメントで確かめた範囲をまとめます。
| 道具 | 呼び名 | 呼び出し方 | 特徴(公式の記述) |
|---|---|---|---|
| VS Code | Snippets | prefix を入力して候補から選ぶ/Tab | JSON(コメント可)で書く。変数・変換が使える |
| IntelliJ IDEA など JetBrains の IDE | Live templates | 略語を入力して Tab | 固定の文・変数つき・選んだコードを包む型の3種類。sout・psvm など |
| Emmet(VS Code に内蔵) | 省略記法(abbreviation) | HTML・CSS などで省略記法を入力して展開 | 拡張機能なしで使える。独自の snippets.json で増やせる |
| GitLab | Snippets | Web 画面で作成・共有 | 個人用とプロジェクト用。1つごとに Git リポジトリを持ち、保存がコミットになる |
エディタのスニペット
自分の手元で、入力を速くするための定型文
変数・タブストップで「穴あき」にできる
チーム共有は設定ファイルを Git に入れる
共有サービスのスニペット
コードの断片を保存し、URL で人に渡す
公開範囲(公開・非公開・メンバーのみ)を選ぶ
展開の仕組みは無く、読む・コピーするもの
GitLab の公式ドキュメントでは、プロジェクト内のスニペットは「プロジェクトの公開範囲が優先される」と書かれています。公開設定のスニペットでも、非公開のプロジェクトの中ならメンバーだけが見られます。
シェルとPythonでスニペットを管理する(実行結果)
この節では、エディタの外(ターミナルや自作ツール)でスニペットを登録・呼び出す方法が、動かした結果つきで分かります。
よく使うコマンドは、テキストファイル1つを1スニペットにして、穴の部分だけ埋めて表示すると管理しやすくなります。bash の関数1つで作れます。
# snip: テキストファイルをスニペットとして呼び出す小さな関数(~/.bashrc などに書く)
SNIP_DIR="${SNIP_DIR:-$HOME/.snippets}"
snip() {
case "$1" in
""|ls) ls -1 "$SNIP_DIR" ;;
show) cat -- "$SNIP_DIR/$2" ;;
new) ${EDITOR:-vi} "$SNIP_DIR/$2" ;;
*) local body; body=$(<"$SNIP_DIR/$1") || return 1
shift
for kv in "$@"; do body=${body//"{{${kv%%=*}}}"/${kv#*=}}; done
printf '%s\n' "$body" ;;
esac
}
{{url}} のような穴を書いたファイルを置き、名前=値 で埋めた結果です(関数を snip.sh に保存して source した状態)。
$ snip ls
curl-json
find-big
$ snip curl-json url=http://127.0.0.1:8080/users name=Sato
curl -sS -X POST http://127.0.0.1:8080/users \
-H 'Content-Type: application/json' \
-d '{"name":"Sato"}'
$ snip find-big dir=/srv/s4/r17/t200 size=1k
find /srv/s4/r17/t200 -type f -size +1k -printf '%s\t%p\n' | sort -rn | head
$ snip nothing
/srv/s4/r17/t200/shell/snip.sh: line 8:/srv/s4/r17/t200/shell/snippets/nothing: No such file or directory
表示するだけにしておき、確かめてからコピーして実行します。eval "$(snip …)" で直接実行もできましたが、値に記号が入ると別のコマンドになるため、人が読んでから実行する形のほうが安全です。短い1行のコマンドなら alias でも足りるので、使い分けは関連記事「Linux alias設定と.bashrcの書き方|おすすめエイリアス50選」も参考になります。
Python の string.Template で穴あきのスニペットを展開する
Python では標準ライブラリの string.Template で、VS Code と同じ $名前 の形の穴を埋められます。JSON にスニペットを並べ、名前で呼び出す30行ほどのツールです。
"""snip.py: JSON に書いたスニペットを string.Template で展開する"""
import json, sys
from pathlib import Path
from string import Template
STORE = Path(__file__).with_name("snippets.json")
def expand(name: str, values: dict[str, str], strict: bool = True) -> str:
snippets = json.loads(STORE.read_text(encoding="utf-8"))
tpl = Template(snippets[name])
return tpl.substitute(values) if strict else tpl.safe_substitute(values)
if __name__ == "__main__":
name, *pairs = sys.argv[1:]
print(expand(name, dict(p.split("=", 1) for p in pairs)))
$ python3 snip.py main 'body=print("hello")'
def main() -> None:
print("hello")
if __name__ == "__main__":
main()
$ python3 snip.py read-csv (トレースバックの最終行)
KeyError: 'path'
$ python3 snip.py nope (トレースバックの最終行)
KeyError: 'nope'
値を渡し忘れると substitute は KeyError で止まり、safe_substitute は with open("$path", …) のように穴を残したまま返しました。文字の $ は $$ と書きます。うっかり $ 100 と書くと、展開のときに次のエラーになりました。
>>> Template('# 価格は $$100、名前は $name').substitute(name='Sato')
'# 価格は $100、名前は Sato'
>>> Template('# 価格は $ 100').substitute()
ValueError: Invalid placeholder in string: line 1, col 7
VS Code は \$、Python の Template は $$ と、$ の逃がし方が道具ごとに違います。スニペットを別の道具に移すときに崩れやすい点です。
検索結果のスニペットとは(meta descriptionとの関係)
この節では、検索結果に出る説明文(スニペット)がどう作られ、meta description とどう関係するかが、Google の公式ドキュメントに沿って分かります。
検索結果のスニペットは、タイトルと URL の下に出る説明文で、主にページの本文から自動で作られます。 Google 検索セントラルは、検索した語に合う部分が使われるため、同じページでも検索語によって違う文が出ることがある、と説明しています。また、meta description のほうがページを正確に説明していると判断された場合は、そちらが使われることもあります。
meta description とスニペットの関係
Google は個別のサイトのスニペットを手で変えない、とも書かれている
Google の公式ドキュメントにある、meta description を書くときの考え方を表にしました。
| 考え方 | 公式ドキュメントの内容 |
|---|---|
| ページごとに違う文にする | 全ページ同じ説明文にしない。重要なページから書く |
| 中身を正確に要約する | キーワードを並べただけの文にしない |
| 具体的な情報を入れる | 著者・公開日・価格など、ページに関係するデータを入れてよい |
| 長さ | meta description に長さの制限は無い。検索結果では画面の幅に合わせて切られる |
| ページが多いサイト | ページの内容からプログラムで作ることもできる |
「何文字までに収めれば切られないか」の数字は、公式ドキュメントには書かれていません。画面の幅で変わるため、最初の文で答えを言い切り、切られても意味が通る順に書くのが確実です。meta タグの書き方そのものは関連記事「HTML metaタグ一覧|SEO・OGP・viewportのコピペ用テンプレート」で扱っています。
リッチスニペットとリッチリザルト
評価の星・価格・パンくずリストなどが付いた検索結果は、以前は「リッチスニペット」と呼ばれることが多く、今の Google のドキュメントでは「リッチリザルト」と呼ばれています。リッチリザルトは、ページに構造化データ(JSON-LD など)を書くことで対象になります。書き方と検証の手順は関連記事「構造化データJSON-LDの書き方|型別コピペ例と検証手順」で扱っています。
スニペットの表示を制御する(nosnippet・max-snippet・data-nosnippet)
この節では、検索結果に説明文を出さない・短くする・一部だけ使わせない指定と、それを HTML から確かめる方法が分かります。
説明文を「出させない」側は、サイトから指定できます。 Google の robots メタタグのドキュメントにある3つの指定です。
| 指定 | 書き方 | 効果(公式の記述) |
|---|---|---|
| nosnippet | <meta name="robots" content="nosnippet"> |
テキストのスニペットと動画のプレビューを出さない。AI による概要などの形式にも適用される |
| max-snippet | content="max-snippet:120" |
スニペットの最大文字数。0 は nosnippet と同じ、-1 は Google に任せる |
| data-nosnippet | <span data-nosnippet>…</span> |
その部分をスニペットに使わない。付けられるのは span・div・section だけ |
HTML からこれらの指定を取り出す確認スクリプトを、Python の標準ライブラリだけで書きました。公開前のページを手元で確かめる用途です。
"""seocheck.py: HTML から検索結果のスニペットに関わる指定を取り出す"""
import sys
from html.parser import HTMLParser
class P(HTMLParser):
def __init__(self):
super().__init__(); self.title = ""; self.in_title = False
self.desc = None; self.robots = []; self.nosnip = 0
def handle_starttag(self, tag, attrs):
a = dict(attrs)
if tag == "title": self.in_title = True
if tag == "meta" and a.get("name", "").lower() == "description":
self.desc = a.get("content", "")
if tag == "meta" and a.get("name", "").lower() in ("robots", "googlebot"):
self.robots += [x.strip() for x in a.get("content", "").split(",")]
if "data-nosnippet" in a:
self.nosnip += 1
if tag not in ("span", "div", "section"):
print(f" 注意: <{tag} data-nosnippet> は無効(span・div・section のみ) line {self.getpos()[0]}")
def handle_endtag(self, tag):
if tag == "title": self.in_title = False
def handle_data(self, d):
if self.in_title: self.title += d
p = P(); p.feed(open(sys.argv[1], encoding="utf-8").read())
print(f"title : {p.title} ({len(p.title)}字)")
print(f"meta description: {len(p.desc) if p.desc is not None else 'なし'}字")
print(f"robots : {p.robots or 'なし'}")
if "nosnippet" in p.robots: print(" 注意: nosnippet のため説明文は表示されない")
print(f"data-nosnippet : {p.nosnip}か所")
最初に作った確認用のページでは、段落(p 要素)に data-nosnippet を付けていました。スクリプトはそれを無効として知らせました。
$ python3 seocheck.py page.html
注意: <p data-nosnippet> は無効(span・div・section のみ) line 8
title : スニペットとは|サンプルページ (15字)
meta description: 87字
robots : ['max-snippet:120']
data-nosnippet : 1か所
(p を span・div・section のいずれかに直したあと)
$ python3 seocheck.py page.html
title : スニペットとは|サンプルページ (15字)
meta description: 87字
robots : ['max-snippet:120']
data-nosnippet : 1か所
(max-snippet:120 を nosnippet に変えたページ)
robots : ['nosnippet']
注意: nosnippet のため説明文は表示されない
- 1data-nosnippet は span・div・section に付けるp や li に付けても効かない。手元の確認でも最初に間違えた
- 2タグを正しく閉じる閉じていないと、その後ろ全部が対象になる(公式の注意)
- 3JavaScript で後から付け外ししない描画の前後で結果が変わるため、避けるよう書かれている
- 4nosnippet は説明文全部を消す一部だけ隠したいなら data-nosnippet を使う
強調スニペットとは(考え方と、クリック後の動き)
この節では、強調スニペットが何で、サイト側にできることとできないことが分かります。
強調スニペットは、検索結果の最上部に出る特別な枠で、説明文が上、ページのタイトルと URL が下に出ます。 Google 検索セントラルは、ページの内容が検索に対する答えにふさわしいと Google のシステムが判断したときに表示され、サイト側からマークアップで指定することはできない、と説明しています。
- 1質問の形の見出しを置く「スニペットとは」など、検索される言い回しを見出しにする
- 2見出しの直後で答えを言い切る1〜2文で定義を書き、前置きを後ろに回す
- 3手順はリスト、比較は表にする読む人にとって拾いやすい形が、検索エンジンにも拾いやすい
- 4出したくないなら nosnippetmax-snippet を短くしても、出なくなる保証は無い(公式)
1〜3は読者にとって読みやすい書き方で、強調スニペットに選ばれる保証ではありません。公式ドキュメントにある確かな操作は4の「出さない」側だけです。
クリックするとページの途中に移る(テキストフラグメント)
公式ドキュメントでは、強調スニペットをクリックすると、ページの該当する部分に直接移ると説明されています。ブラウザが対応していない場合や移る先を決められない場合は、ページの先頭に移ります。この「途中に移る」動きは、URL の #:~:text=(テキストフラグメント)でブラウザが文字を探してスクロールする仕組みと同じ形です。手元のページ(高さ 5,068px)を Chromium で開き、スクロール位置を測りました。
| 開いた URL の末尾 | scrollY | location.hash |
|---|---|---|
| (なし) | 0 | (空) |
#vscode(id へのリンク) | 2,573 | #vscode |
#:~:text=VS Code では prefix | 2,278 | (空) |
#:~:text=存在しない文 | 0 | (空) |
テキストフラグメントは id が無くても、指定した文の位置まで移りました。見つからない文を指定すると、エラーにならず先頭のままです。また、#:~:text= の部分は JavaScript の location.hash から見えませんでした。ページの JavaScript でハッシュを読んで処理をしているサイトでも、この部分で動きが変わることはありません。
よくある質問
この節では、スニペットについてよく調べられている疑問に短く答えます。
Q. スニペットとテンプレートは何が違いますか?
A. どちらも「型を使い回す」ものですが、スニペットはコードや文の一部分に差し込む短いまとまり、テンプレートはファイルや文書全体の雛形を指すことが多いです。VS Code では、スニペットに isFileTemplate を付けるとファイル全体の雛形として使えます。
Q. スニペットと Emmet は同じものですか?
A. 別のものです。Emmet は ul>li*3 のような省略記法から HTML・CSS を組み立てる仕組みで、VS Code に内蔵されています。スニペットは登録した定型文を呼び出す仕組みです。prefix が Emmet の記法と重なると、思った形にならないことがあります。
Q. VS Code のスニペットをチームで共有するには?
A. プロジェクトの .vscode フォルダーに 〇〇.code-snippets を置き、Git に入れます。そのフォルダーを開いた人全員が使えます。壊れたファイルを入れないよう、この記事の検証スクリプトのような確認を CI に入れると安心です。
Q. スニペットのファイルに日本語を書けますか?
A. 書けます。この記事の検証でも、description とコメントに日本語を入れたファイルを問題なく読み込めました。ファイルは UTF-8 で保存します。
Q. 検索結果のスニペットを自分で決められますか?
A. 決められません。meta description を書くと候補にはなりますが、どの文を出すかは Google が検索語ごとに決めます。サイト側で確実にできるのは、nosnippet・max-snippet・data-nosnippet で「出させない・短くする」ことです。
Q. meta description は何文字で書けばよいですか?
A. Google の公式ドキュメントには長さの制限が無く、検索結果では画面の幅に合わせて切られる、と書かれています。決まった文字数より、最初の文で答えを言い切り、切られても意味が通る順に書くことが大切です。
Q. 強調スニペットに選ばれるとアクセスは増えますか?
A. 一番上に表示されるので目に入りやすくなりますが、答えが枠の中で読めてしまい、クリックされない場合もあります。増えるかどうかは検索語によって違うため、Search Console の表示回数とクリック数で確かめます。
Q. 「リッチスニペット」と「強調スニペット」の違いは?
A. リッチスニペット(今の Google の呼び名はリッチリザルト)は、普通の検索結果に星や価格などの情報が付いたもので、構造化データで対象になれます。強調スニペットは、最上部の回答の枠で、マークアップでは指定できません。
Q. スニペットで $ を使う言語(PHP・シェル)の定型文を作るには?
A. JSON の body の中で \\$ と書きます。手元の確認では、"echo \\$name;" が echo $name; と展開されました。エスケープしないと echo ; になりました。
Q. コードスニペットをそのまま業務で使ってよいですか?
A. 載っているサイトの利用条件(ライセンス)を確かめてから使います。また、記事のスニペットは前提(版・import・設定)が省かれていることが多いので、手元で動かし、意味を理解してから入れるのが安全です。
まとめ
- スニペットは「断片・抜粋」という意味。IT では、コードの断片、エディタの定型文の機能、検索結果の説明文の3つを指す。
- VS Code のスニペットは JSON(コメント可)で書き、
$1・${1:既定値}・${1|a,b|}・$0で入力位置を作る。同じ番号は連動する。 - 変数(ファイル名・日付・UUID・コメント記号)と変換(pascalcase など7種)で、ファイル名からクラス名まで作れる。その言語に無いコメントの形は空になる。
- いちばん多いつまずきは
$が消えること。JSON の中では\\$と書く。Python の Template では$$。 - 検索結果のスニペットは主に本文から自動で作られ、meta description は候補の1つ。サイト側で確実にできるのは nosnippet・max-snippet・data-nosnippet(span・div・section のみ)で出させない・短くすることで、強調スニペットは指定できない。
参考・出典
確認日はいずれも 2026年10月29日です。
- Visual Studio Code「Snippets in Visual Studio Code」:https://code.visualstudio.com/docs/editing/userdefinedsnippets
- Visual Studio Code「Emmet in Visual Studio Code」:https://code.visualstudio.com/docs/languages/emmet
- Monaco Editor(npm パッケージ monaco-editor 0.57.0):https://www.npmjs.com/package/monaco-editor
- jsonc-parser(npm パッケージ 3.3.1):https://www.npmjs.com/package/jsonc-parser
- JetBrains「Live templates」(IntelliJ IDEA ドキュメント):https://www.jetbrains.com/help/idea/using-live-templates.html
- GitLab Docs「Snippets」:https://docs.gitlab.com/user/snippets/
- Python ドキュメント「string — 一般的な文字列操作」(テンプレート文字列):https://docs.python.org/ja/3/library/string.html#template-strings
- Google 検索セントラル「検索結果のスニペットを管理する」:https://developers.google.com/search/docs/appearance/snippet?hl=ja
- Google 検索セントラル「強調スニペットとウェブサイト」:https://developers.google.com/search/docs/appearance/featured-snippets?hl=ja
- Google 検索セントラル「Robots meta タグ、data-nosnippet、X-Robots-Tag の指定」:https://developers.google.com/search/docs/crawling-indexing/robots-meta-tag?hl=ja
本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。
(記載例)出典:株式会社RJC「スニペットとは?コード・VS Code・検索結果の3つの意味を実例で」
株式会社RJC ― SI事業・SES事業・AI駆動開発。RJCは一緒に成長を楽しめる会社です。
WE ARE HIRING
RJCで一緒に開発しながら、
成長を楽しみませんか?
RJCは、Web・モバイル・AIを活用した開発プロジェクトで、テックリードやPM・PMOも活躍するシステム開発会社です。会社を知る、待遇を確かめる、話を聞いてみる。気になるところ見てみてください!
- 127日年間休日
- 12時間平均残業時間
- 毎日ガチャ遊びココロも大切にする福利厚生。アマギフなどの賞品ラインナップ!
ほかにも、チケットレストラン、書籍読み放題、2年ごとの慰労報奨(休暇 or 金一封)、11期連続の黒字決算。