Reactアプリにプログレスバーを手軽に組み込める@bprogress/reactを試してみた

Reactアプリにプログレスバーを手軽に組み込める@bprogress/reactを試してみた

ルーター非依存のプログレスバーライブラリ @bprogress/react を紹介。useProgress フックで start() / stop() を呼ぶだけのシンプルな設計で、色・高さ・イージングなど豊富なカスタマイズが可能です。
2026.04.02

Webアプリでページ遷移やデータ取得中に、「今何かロードしてるんだよ、待っててね」って手軽に画面に表示したいときってありますよね?

@bprogress/react を使うと、ルーターに依存せずReactアプリへ簡単にプログレスバーを組み込めます。
触ってみたら思ったよりも自由度が高くて面白かったので紹介します。

まずはStackBlitzのデモを触ってみてください。
Fetch data をクリックすると、2秒間上部にバーが走ってロード中の雰囲気が出ます。

@bprogress/reactとは

@bprogress/react はNProgressをベースにした、TypeScript製のプログレスバーライブラリです。

https://bprogress.vercel.app/docs/

特徴的なのは ルーター非依存 である点です。
Next.js向けの next-nprogress-bar のようなライブラリはルーターのイベントに自動でフックしますが、@bprogress/reactuseProgress フックで start() / stop() を自分で呼ぶ設計になっています。「自動でやってほしい」という場合には useAnchorProgress フックも用意されていますが、基本的には自分で制御する前提のライブラリです。

React以外にもNext.js・Remix・Vue向けの専用パッケージが用意されています。

インストール

npm install @bprogress/react
# or
pnpm add @bprogress/react

基本的な使い方

1. ProgressProviderでアプリ全体をラップする

ProgressProvider をアプリのルートに配置します。disableStyle を指定するとデフォルトのスタイルを無効化でき、後述の css() 関数で独自スタイルを完全に制御できます。

src/main.tsx
import { ProgressProvider } from '@bprogress/react';
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App.tsx';

ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render(
  <React.StrictMode>
    <ProgressProvider disableStyle>
      <App />
    </ProgressProvider>
  </React.StrictMode>
);

2. useProgressフックでバーを操作する

useProgress フックが返す start() / stop() / pause() / resume() でバーをコントロールします。

src/App.tsx
import { useProgress } from '@bprogress/react';

function App() {
  const { start, stop, pause, resume } = useProgress();

  return (
    <div>
      <button onClick={() => start()}>start()</button>
      <button onClick={() => stop()}>stop()</button>
      <button onClick={() => pause()}>pause()</button>
      <button onClick={() => resume()}>resume()</button>
    </div>
  );
}

非常にシンプルです。APIフェッチと組み合わせる場合は次のようになります。

const { start, stop } = useProgress();

const handleFetch = async () => {
  start();
  await fetchData();
  stop();
};

デモで確認できる機能

今回作ったデモでは以下の項目をインタラクティブに切り替えられます。

項目 内容
Basic controls start() / stop() / pause() / resume() を手動で呼ぶ
Simulated fetch start() → 2秒待機 → stop() でAPIフェッチをシミュレート
Color バーの色をBlue / Green / Pink / Orangeから選択
Height バーの太さを2px / 3px / 4px / 6pxから選択
Speed アニメーション速度をSlow / Normal / Fastから選択
Easing アニメーションの変化関数(linear / ease / ease-in-out / cubic-bezier
Spinner スピナーの表示・非表示と表示位置(4隅)
Direction バーが伸びる方向(LTR(Left To Right) / RTL(Right To Left))
Trickle 自動で少しずつ進む"trickle"機能のON/OFFと速度

カスタマイズ方法

setOptions()で動的に変更する

useProgress が返す setOptions() を使うと、実行時にオプションを変更できます。

const { setOptions } = useProgress();

// アニメーション速度を変更
setOptions({ speed: 800 });

// イージングを変更
setOptions({ easing: "cubic-bezier(0.34, 1.56, 0.64, 1)" });

// スピナーを表示する
setOptions({ showSpinner: true });

// RTLモードに切り替える
setOptions({ direction: "rtl" });

// trickle(自動進行)を無効化する
setOptions({ trickle: false });

css()関数でスタイルを動的に変更する

@bprogress/corecss() 関数を使うと、色・高さ・スピナー位置をまとめたCSS文字列を生成できます。それを <style> タグに流し込むことで、まとめてスタイルを切り替えられます。

import { css } from "@bprogress/core";
import type { SpinnerPosition } from "@bprogress/react";

function applyProgressCss(
  color: string,
  height: string,
  spinnerPosition: SpinnerPosition,
) {
  const id = "bprogress-custom";
  let el = document.getElementById(id) as HTMLStyleElement | null;
  if (!el) {
    el = document.createElement("style");
    el.id = id;
    document.head.appendChild(el);
  }
  el.textContent = css({ color, height, spinnerPosition });
}

// 色・高さ・スピナー位置を一括変更
applyProgressCss("#22c55e", "4px", "top-right");

おわりに

@bprogress/react を試してみました。ルーター非依存で useProgress フックを呼ぶだけというシンプルな設計が気に入りました。
軽くロード中であることを見せるのに使えそうです。

Next.jsやRemix向けの専用パッケージも用意されているので、フレームワークを使っている場合はそちらも検討してみてください。

この記事をシェアする

関連記事