タイトル: 個別のページにcssやjsを反映させる方法
SEOタイトル: 【Laravel】個別のページ(Bladeテンプレート)にcssやjsを反映させる方法
この本文には実行可能なタグ等が含まれるため、安全のためHTMLソースとして表示しています。本文データは変更していません。
<table border="1" cellpadding="1" cellspacing="1" style="width:1000px">
<thead><tr><th style="background-color:#f39c12;color:#ffffff;text-align:left">この記事の要点</th></tr></thead>
<tbody><tr><td style="background-color:#fef9e7"><ul>
<li>Laravel Blade で<strong>特定ページにだけ CSS / JS を読み込む</strong>方法</li>
<li>レイアウトに <code>@stack</code> / <code>@section</code> プレースホルダを定義</li>
<li>個別 view から <code>@push</code> / <code>@section</code> で追加</li>
<li>一般的に <code>@stack('styles')</code> / <code>@stack('scripts')</code> を <code><head></code> や <code></body></code> 前に配置</li>
<li>優先度の高い順 (e.g. Bootstrap → カスタム) で出力されるよう書く</li>
</ul></td></tr></tbody>
</table>
<p> </p>
<h2>方法 1: @stack / @push(推奨)</h2>
<p>同じプレースホルダに複数箇所から追加できる「stack」を使う方法。</p>
<h3>レイアウト側</h3>
<pre style="background:#0f172a;color:#e2e8f0;padding:1em;border-radius:6px;overflow-x:auto;font-family:Consolas,Monaco,monospace;font-size:0.9em;line-height:1.5"><code><!-- resources/views/layouts/app.blade.php -->
<!DOCTYPE html>
<html>
<head>
<title>@yield('title')</title>
<!-- 共通 CSS -->
<link href="{{ asset('css/app.css') }}" rel="stylesheet">
<!-- ページ固有 CSS の挿入箇所 -->
@stack('styles')
</head>
<body>
@yield('content')
<!-- 共通 JS -->
<script src="{{ asset('js/app.js') }}"></script>
<!-- ページ固有 JS の挿入箇所 -->
@stack('scripts')
</body>
</html></code></pre>
<h3>個別ページ側</h3>
<pre style="background:#0f172a;color:#e2e8f0;padding:1em;border-radius:6px;overflow-x:auto;font-family:Consolas,Monaco,monospace;font-size:0.9em;line-height:1.5"><code><!-- resources/views/users/index.blade.php -->
@extends('layouts.app')
@section('title', 'ユーザー一覧')
@push('styles')
<link href="{{ asset('css/users.css') }}" rel="stylesheet">
<style>
.user-card { padding: 1em; }
</style>
@endpush
@section('content')
<h1>ユーザー一覧</h1>
<div class="user-list">
@foreach ($users as $user)
<div class="user-card">{{ $user->name }}</div>
@endforeach
</div>
@endsection
@push('scripts')
<script src="{{ asset('js/users.js') }}"></script>
<script>
document.querySelectorAll(".user-card").forEach(card => {
card.addEventListener("click", () => console.log("clicked"));
});
</script>
@endpush</code></pre>
<h2>方法 2: @section / @yield</h2>
<p>1 箇所からの挿入のみ (上書き) で十分なケース。</p>
<pre style="background:#0f172a;color:#e2e8f0;padding:1em;border-radius:6px;overflow-x:auto;font-family:Consolas,Monaco,monospace;font-size:0.9em;line-height:1.5"><code><!-- layouts/app.blade.php -->
<head>
<link href="{{ asset('css/app.css') }}" rel="stylesheet">
@yield('styles')
</head>
<body>
@yield('content')
<script src="{{ asset('js/app.js') }}"></script>
@yield('scripts')
</body>
<!-- users/index.blade.php -->
@extends('layouts.app')
@section('styles')
<link href="{{ asset('css/users.css') }}" rel="stylesheet">
@endsection
@section('content')
...
@endsection
@section('scripts')
<script src="{{ asset('js/users.js') }}"></script>
@endsection</code></pre>
<h2>@push vs @section の使い分け</h2>
<table border="1" cellpadding="1" cellspacing="1" style="width:1000px">
<thead><tr><th>項目</th><th>@stack / @push</th><th>@yield / @section</th></tr></thead>
<tbody>
<tr><td>挿入箇所</td><td>複数 view から追加可能</td><td>1 つの section を 1 つの view が定義</td></tr>
<tr><td>順序</td><td>追加順(先 → 後)</td><td>1 つだけ</td></tr>
<tr><td>用途</td><td>レイアウト + コンポーネント両方から script 追加</td><td>ページ固有の単一 CSS / JS</td></tr>
<tr><td>パーシャル / コンポーネント内から使える</td><td>○ @push</td><td>× (@yield は section 1 つに限定)</td></tr>
</tbody>
</table>
<h2>@once で重複防止</h2>
<p>パーシャル (含めるパーツ) を複数回 include しても、CSS / JS は 1 回だけ読み込みたい:</p>
<pre style="background:#0f172a;color:#e2e8f0;padding:1em;border-radius:6px;overflow-x:auto;font-family:Consolas,Monaco,monospace;font-size:0.9em;line-height:1.5"><code><!-- partials/datepicker.blade.php -->
@once
@push('styles')
<link href="{{ asset('css/datepicker.css') }}" rel="stylesheet">
@endpush
@push('scripts')
<script src="{{ asset('js/datepicker.js') }}"></script>
@endpush
@endonce
<input type="text" class="datepicker">
<!-- 利用側 (datepicker を 3 回 include しても CSS/JS は 1 回だけ) -->
@include('partials.datepicker')
@include('partials.datepicker')
@include('partials.datepicker')</code></pre>
<h2>@prepend (先頭に追加)</h2>
<p>後から追加するけど stack の<strong>先頭</strong>に置きたい(jQuery より先に Polyfill 等):</p>
<pre style="background:#0f172a;color:#e2e8f0;padding:1em;border-radius:6px;overflow-x:auto;font-family:Consolas,Monaco,monospace;font-size:0.9em;line-height:1.5"><code>@prepend('scripts')
<script src="https://polyfill.io/v3/polyfill.min.js"></script>
@endprepend</code></pre>
<h2>Vite との統合</h2>
<p>Laravel 10+ はデフォルトで Vite を使う:</p>
<pre style="background:#0f172a;color:#e2e8f0;padding:1em;border-radius:6px;overflow-x:auto;font-family:Consolas,Monaco,monospace;font-size:0.9em;line-height:1.5"><code><!-- レイアウト -->
<head>
@vite(['resources/css/app.css', 'resources/js/app.js'])
@stack('styles')
</head>
<body>
@yield('content')
@stack('scripts')
</body>
<!-- 個別ページ -->
@push('styles')
@vite(['resources/css/users.css'])
@endpush
@push('scripts')
@vite(['resources/js/users.js'])
@endpush
# Vite が hot reload + バンドル + cache busting を自動化</code></pre>
<h2>条件付き読み込み</h2>
<pre style="background:#0f172a;color:#e2e8f0;padding:1em;border-radius:6px;overflow-x:auto;font-family:Consolas,Monaco,monospace;font-size:0.9em;line-height:1.5"><code>@push('scripts')
@if (auth()->check())
<script src="{{ asset('js/authenticated-user.js') }}"></script>
@endif
@env('production')
<script src="{{ asset('js/analytics.js') }}"></script>
@endenv
@if (config('app.feature.chat'))
<script src="{{ asset('js/chat.js') }}"></script>
@endif
@endpush</code></pre>
<h2>パフォーマンスの考慮</h2>
<ul>
<li><strong>defer / async</strong>: <code><script src="..." defer></code> でレンダーブロック回避</li>
<li><strong>preload</strong>: <code><link rel="preload" href="..." as="script"></code> で先読み</li>
<li><strong>Critical CSS</strong>: 重要な CSS はインラインで <code><style></code></li>
<li><strong>Vite で自動最適化</strong>: コード分割・遅延読み込みが自動</li>
</ul>
<pre style="background:#0f172a;color:#e2e8f0;padding:1em;border-radius:6px;overflow-x:auto;font-family:Consolas,Monaco,monospace;font-size:0.9em;line-height:1.5"><code>@push('scripts')
<script src="{{ asset('js/users.js') }}" defer></script>
@endpush
@push('styles')
<link rel="preload" href="{{ asset('fonts/Noto.woff2') }}" as="font" type="font/woff2" crossorigin>
@endpush</code></pre>
<h2>関連記事</h2>
<ul>
<li><a href="/article/21319">ヘッダー/フッターの共通コンポーネント</a></li>
<li><a href="/article/21303">aリンクの貼り方と動的URLの作成</a></li>
</ul>