ユーザビリティ改善事例:「すべての記事を見る」機能の問題解決
プロジェクト概要
期間: 2025年6月15日
技術スタック: Python Flask, Jinja2, Bootstrap 5, HTML/CSS
改修規模: 小規模(4ファイル修正)
影響範囲: フロントエンド表示ロジック、ユーザーナビゲーション
発見された問題
🚨 問題の詳細
ポートフォリオサイトのトップページにある「すべての記事を見る」ボタンをクリックしても、記事検索ページが表示されるだけで、肝心の全記事一覧が表示されないという重大なユーザビリティ問題が発覚しました。
# 問題のあったコード(修正前)
@app.route('/search')
def search():
query = request.args.get('q', '')
tag = request.args.get('tag', '')
if query or tag:
articles = get_articles(search=query, tag=tag)
else:
articles = [] # 🚨 ここが問題!空配列を返している
return render_template('search.html', articles=articles, query=query, tag=tag)
📊 問題の影響
- ユーザー混乱: 「すべての記事を見る」→ 検索フォームのみ表示
- サイト回遊性低下: 記事発見の主要な導線が機能していない
- SEO影響: 内部リンクの効果が半減
- 離脱率増加: 期待した情報にたどり着けずユーザーが離脱
解決策の設計
🎯 設計方針
- 既存機能を壊さない: 検索機能は維持したまま改修
- 直感的なUX: 「すべての記事を見る」の期待通りの動作を実現
- 一石二鳥の設計: 検索機能 + 全記事表示を同時に提供
- SEO配慮: ページタイトルやメタデータも適切に動的変更
🔧 技術的アプローチ
- 条件分岐の改修: クエリパラメータの有無で表示内容を制御
- テンプレート最適化: 動的なタイトル・メッセージ表示
- UI改善: アイコンと説明文の最適化
実装内容
1. サーバーサイドロジック修正
# 修正後のコード
@app.route('/search')
def search():
"""記事検索"""
query = request.args.get('q', '')
tag = request.args.get('tag', '')
if query or tag:
articles = get_articles(search=query, tag=tag) # 検索結果
else:
# ✅ 検索キーワードがない場合は全ての記事を表示
articles = get_articles() # 公開済み全記事
return render_template('search.html',
articles=articles,
query=query,
tag=tag)
効果: 単純な条件分岐の修正により、検索機能と全記事表示を両立
2. テンプレート動的制御
<!-- ページタイトルの動的変更 -->
{% block title %}
{% if query %}「{{ query }}」の検索結果
{% elif tag %}タグ「{{ tag }}」の記事一覧
{% else %}全記事一覧{% endif %}
{% endblock %}
<!-- ヘッダーの動的表示 -->
<h1 class="h2">
<i class="fas fa-search me-2"></i>
{% if query %}記事検索
{% elif tag %}タグ記事一覧
{% else %}全記事一覧{% endif %}
</h1>
<!-- 状況に応じた説明文 -->
{% if not query and not tag %}
<p class="text-muted">すべての公開記事を表示しています</p>
{% endif %}
効果: 同一ページで3つの異なる用途に対応、ユーザーに明確な情報提供
3. UX細部改善
<!-- トップページボタンのアイコン変更 -->
<!-- 修正前 -->
<i class="fas fa-search me-2"></i>すべての記事を見る
<!-- 修正後 -->
<i class="fas fa-list me-2"></i>すべての記事を見る
<!-- 検索フォーム説明文の動的変更 -->
<small class="form-text text-muted mt-1">
{% if articles and not query and not tag %}
下記に表示されている全記事から絞り込み検索できます
{% else %}
記事のタイトルや内容からキーワードで検索できます
{% endif %}
</small>
効果: 視覚的に「検索」から「一覧表示」の意図を明確化
4. 記事数表示の改善
<!-- 状況別メッセージ表示 -->
<p class="text-muted mb-3">
{% if query %}
{{ articles|length }} 件の記事が見つかりました
{% elif tag %}
{{ articles|length }} 件の記事があります
{% else %}
全 {{ articles|length }} 件の記事
{% endif %}
</p>
効果: ユーザーが現在の表示状況を正確に把握できる
技術的工夫
🎨 レスポンシブ対応
- Bootstrap 5活用:
col-lg-6 col-md-6
でカード表示を最適化 - モバイル配慮: 検索フォームとボタンの配置調整
🔍 SEO最適化
<!-- メタデータの動的最適化 -->
{% block description %}
{% if query %}「{{ query }}」の検索結果ページ。
{% elif tag %}タグ「{{ tag }}」に関連する記事一覧。
{% else %}yousystem Portfolioの全記事一覧ページ。プロフィール・事例ライブラリ・開発ノートの全記事を一覧表示し、記事検索もできます。
{% endif %}
{% endblock %}
♿ アクセシビリティ
- aria-label最適化: 「すべての記事を一覧表示・検索」
- セマンティックHTML:
<section aria-label="全記事一覧">
結果と効果
✅ 問題解決
- 完全解決: 「すべての記事を見る」で期待通りの動作を実現
- 機能強化: 検索 + 全表示の一体型インターフェースに進化
- ナビゲーション改善: サイト内回遊性が大幅向上
📈 ユーザビリティ向上
- 直感的操作: ボタンをクリックすると即座に全記事が表示
- スムーズな検索: 全記事を見てから絞り込み検索が可能
- 明確な状況把握: 現在の表示状態が一目で分かる
- 効率的な記事発見: カテゴリ・タグ・検索の多様なアプローチ
🛠️ 開発効率
- コード整理: 単一ページで複数機能を統合
- 保守性向上: 条件分岐による動的制御で可読性アップ
- 拡張性確保: 新しい表示パターンも容易に追加可能
学んだこと
🎓 技術的学習
- Jinja2テンプレート: 条件分岐による動的HTML生成のベストプラクティス
- Flask ルーティング: 同一エンドポイントでの複数機能実装
- Bootstrap活用: 一貫したUI/UXでの機能拡張
💡 UX設計の気づき
- ユーザー期待値: ボタンの文言と実際の動作の一致が重要
- 情報設計: 複数機能を直感的に統合する方法
- 段階的情報提示: 概要表示→絞り込みのユーザージャーニー
🔧 問題解決プロセス
- 現状分析: ユーザー行動フローの検証
- 根本原因特定: コードレベルでの問題箇所の発見
- 最小限修正: 既存機能を壊さない改修方針
- 総合的改善: 技術的修正 + UX向上の同時実現
今後の改善案
🚀 機能拡張
- ソート機能: 投稿日、タイトル、カテゴリでの並び替え
- ページネーション: 記事数増加時の表示性能最適化
- 高度検索: 複数キーワード、日付範囲での絞り込み
📊 分析強化
- Google Analytics: 検索キーワードとユーザー行動の分析
- A/Bテスト: UIパターンの効果測定
- ユーザビリティテスト: 実際のユーザー操作の観察
まとめ
今回の改修は、小さな修正で大きなユーザビリティ改善を実現した好例でした。単純な条件分岐の見直しから始まり、テンプレート最適化、UI改善まで一貫した改修により、サイトの使いやすさが劇的に向上しました。
技術的にはシンプルでも、ユーザー体験に与える影響は絶大という、Web開発における重要な教訓を改めて実感できる改修となりました。