【初心者向け】超シンプルなTodoリストWebアプリを数時間で作ってGitHub Pagesで公開する方法

## はじめに

「アプリ開発を始めたいけれど、いきなりネイティブアプリや複雑なフレームワークはハードルが高い…」  
「とにかく最初は何かを”作って公開”して、経験とモチベーションを積み上げたい」

そんな方にピッタリの手順をご紹介します。

本記事では、**ローカルストレージで動く超シンプルなTodoリストWebアプリ**を、わずか数時間で作成し、**GitHub Pages**でURL公開するまでの流れを解説します。複雑な開発環境は不要、`index.html`ひとつで完結します。

公開後、誰でもそのURLにアクセスしてあなたのTodoアプリを見ることが可能に！ これを足がかりに、PDCAを回してスキルアップしていきましょう。

---

## この記事のゴール

- **開発言語・ツール**：  
  - HTML、CSS、JavaScriptのみ（フレームワーク不要）
  - ブラウザ上で完結、特別なサーバーサイドやビルドツールは不要
- **機能**：  
  - テキスト入力でTodo追加
  - チェックボックスで完了状態を切り替え
  - 削除ボタンで不要なTodoを消去
  - LocalStorageに保存して、ページ再読み込み後も状態を保持
- **デプロイ（公開）**：  
  - GitHubの無料サービス「GitHub Pages」を使い、URLでアクセス可能な形で公開

※今回は**最小機能**に絞り、まず「リリースする」という体験を重視しています。

---

## 目次

1. [準備するもの](#準備するもの)  
2. [TodoリストWebアプリの仕組み](#todoリストwebアプリの仕組み)  
3. [サンプルコード全体（index.htmlのみ）](#サンプルコード全体indexhtmlのみ)  
4. [ローカルで動作確認](#ローカルで動作確認)  
5. [GitHubにアップロード](#githubにアップロード)  
    - [方法A: ブラウザで直接アップロード](#方法a-ブラウザで直接アップロード)  
    - [方法B: Gitコマンドでプッシュ](#方法b-gitコマンドでプッシュ)  
6. [GitHub Pagesでの公開設定](#github-pagesでの公開設定)  
7. [公開URLへのアクセス](#公開urlへのアクセス)  
8. [PDCAを回そう](#pdcaを回そう)  
9. [次の一歩（発展案）](#次の一歩発展案)  
10. [まとめ](#まとめ)

---

## 準備するもの

- **GitHubアカウント**（無料で作成可能）  
- **エディタ**（VSCodeなど、テキストが編集できればOK）  
- **ブラウザ**（ChromeやSafariなど）

これらがあれば特別な環境構築は不要です。

---

## TodoリストWebアプリの仕組み

今回のTodoリストは以下のような流れで動きます。

1. **LocalStorageからTodoを読み込む**  
   - ブラウザに組み込まれた簡易データ保存領域を利用。
   
2. **画面表示**  
   - 読み込んだTodoをリスト表示し、チェックボックスや削除ボタンを設置。
   
3. **Todo追加**  
   - ユーザーが入力フォームで新しいTodoを追加すると、配列に挿入しLocalStorageへ再保存。
   
4. **完了・削除操作**  
   - チェックボックスや削除ボタン操作のたびに、配列・LocalStorageを更新。
   
5. **永続化**  
   - ページを閉じても、次回開いたときに最後の状態が維持される。

これだけで「動くサービス」が実現します。

---

## サンプルコード全体（index.htmlのみ）

以下のコードを`index.html`としてローカルに保存します。  
このファイルひとつでTodoリストが完成します。

```html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Todo List</title>
<style>
  body {
    font-family: sans-serif;
    max-width: 400px;
    margin: 20px auto;
  }
  h1 {
    text-align: center;
  }
  .input-area {
    display: flex;
    gap: 10px;
    margin-bottom: 10px;
  }
  .input-area input[type="text"] {
    flex: 1;
    padding: 8px;
    font-size: 1rem;
  }
  .input-area button {
    padding: 8px;
  }
  ul {
    list-style-type: none;
    padding: 0;
  }
  li {
    display: flex;
    align-items: center;
    gap: 10px;
    border-bottom: 1px solid #ccc;
    padding: 5px 0;
  }
  .done-text {
    text-decoration: line-through;
    color: #aaa;
  }
  .delete-btn {
    margin-left: auto;
    color: #fff;
    background: #d33;
    border: none;
    padding: 5px 10px;
    cursor: pointer;
  }
  .delete-btn:hover {
    background: #a11;
  }
</style>
</head>
<body>

<h1>Todo List</h1>
<div class="input-area">
  <input type="text" id="todo-input" placeholder="やることを入力" />
  <button id="add-btn">追加</button>
</div>
<ul id="todo-list"></ul>

<script>
  function loadTodos() {
    const stored = localStorage.getItem('todos');
    return stored ? JSON.parse(stored) : [];
  }

  function saveTodos(todos) {
    localStorage.setItem('todos', JSON.stringify(todos));
  }

  const inputEl = document.getElementById('todo-input');
  const addBtn = document.getElementById('add-btn');
  const todoListEl = document.getElementById('todo-list');

  let todos = loadTodos();

  function renderTodos() {
    todoListEl.innerHTML = '';
    todos.forEach((todo, index) => {
      const li = document.createElement('li');

      const checkbox = document.createElement('input');
      checkbox.type = 'checkbox';
      checkbox.checked = todo.done;
      checkbox.addEventListener('change', () => {
        todos[index].done = checkbox.checked;
        saveTodos(todos);
        renderTodos();
      });

      const span = document.createElement('span');
      span.textContent = todo.text;
      if (todo.done) {
        span.classList.add('done-text');
      }

      const delBtn = document.createElement('button');
      delBtn.textContent = '削除';
      delBtn.classList.add('delete-btn');
      delBtn.addEventListener('click', () => {
        todos.splice(index, 1);
        saveTodos(todos);
        renderTodos();
      });

      li.appendChild(checkbox);
      li.appendChild(span);
      li.appendChild(delBtn);
      todoListEl.appendChild(li);
    });
  }

  function addTodo() {
    const text = inputEl.value.trim();
    if (text) {
      todos.push({ text: text, done: false });
      saveTodos(todos);
      renderTodos();
      inputEl.value = '';
    }
  }

  addBtn.addEventListener('click', addTodo);
  inputEl.addEventListener('keydown', (e) => {
    if (e.key === 'Enter') {
      addTodo();
    }
  });

  renderTodos();
</script>

</body>
</html>
```
---
## ローカルで動作確認

1. `index.html`をダブルクリックしてブラウザで開く  
2. テキストボックスにTodoを入力し、「追加」ボタンをクリック  
3. 下部にTodoが表示され、完了チェックや削除が動作するか確認

問題なければ次は公開しましょう。

---

## GitHubにアップロード

GitHub Pagesで公開するには、GitHub上にファイルを置きます。  
以下はGitHub Pagesのために`main`ブランチ直下に`index.html`を置くシンプルな手順です。

### 方法A: ブラウザで直接アップロード

1. GitHubにログインし、右上の「＋」→「New repository」で新規リポジトリ（Public）を作成  
2. リポジトリトップで「Add file」→「Upload files」をクリック  
3. 先ほどの`index.html`をドラッグ＆ドロップ  
4. 「Commit changes」を押してアップロード

### 方法B: Gitコマンドでプッシュ

```bash
# ローカル作業用ディレクトリ作成
mkdir my-todo-app
cd my-todo-app

# index.htmlをこのフォルダに配置

git init
git add index.html
git commit -m "Initial commit"

# GitHubリポジトリをremoteに追加（URLは自分のアカウントに変更）
git remote add origin https://github.com/<ユーザー名>/<リポジトリ名>.git
git push -u origin main
```
---

## GitHub Pagesでの公開設定

1. リポジトリページで「Settings」タブを開く  
2. 左サイドバーから「Pages」を探す  
3. 「Build and deployment」セクションの「Source」で`main`ブランチ、`(root)`を選択して「Save」をクリック  
4. 数十秒～数分待つと、GitHub Pagesが有効化されます

---

## 公開URLへのアクセス

有効化後、`https://<ユーザー名>.github.io/<リポジトリ名>/` のようなURLが表示されます。そのURLにアクセスすると、先ほどのTodoリストがネット上で公開されているはずです！

- スマホやタブレット、別のPCからでもアクセス可能  
- 更新したら`git push`で即反映

---

## PDCAを回そう

ここまでで「作ったものを公開」する一連の流れを経験できました。  
あとは改善、機能追加、デザイン変更、コード整理などを行い、`git push`するだけで改善版が即時公開されます。

- **Plan（計画）**：もっと良いUIにしたい  
- **Do（実行）**：CSSを改良してpush  
- **Check（評価）**：公開URLで見た目チェック  
- **Act（改善）**：さらに修正や機能拡張、PWA化など

このサイクルを繰り返すうちに、自然とスキルが身についていきます。

---

## 次の一歩（発展案）

- **デザイン強化**：CSSフレームワーク（Bulma, Tailwindなど）を使う  
- **PWA化**：manifest.jsonやService Workerを追加してオフライン対応  
- **ユーザー別保存**：FirebaseやSupabaseでログイン機能＋クラウド保存を実現  
- **タグ付け・検索機能**：より実用的なTodo管理ツールへアップグレード

---

## まとめ

- 超シンプルなTodoリストWebアプリは、HTML/CSS/JSとLocalStorageで数時間で完成  
- GitHub Pagesを使えば、無料で即公開可能  
- 一度公開の流れを経験すると、機能追加や改善が圧倒的にラクになる  
- 小さな成功体験が、次の大きなチャレンジへのモチベーションとなる

「とりあえず動くもの」を一度リリースしてみることが、学習や開発スキル向上への大きな一歩です。今後はこの土台を生かして、より高度なアプリ開発へと進んでみてください！