MENU

DifyのUIを改善!フロントエンドのカスタマイズ手順

当ページのリンクには広告が含まれています。

Difyをセルフホスト環境(ローカルやVPS)で運用していると、「ここを少し使いやすくしたい」「独自のダッシュボードを追加したい」といった要望が出てくることがあります。

この記事では、Docker環境で構築したDifyのフロントエンド(Next.js)をカスタマイズし、モバイル版での操作性向上と、独自ダッシュボード画面の追加を行う具体的な手順を解説します。

目次

今回のカスタマイズ内容

以下の2点を実装します。

  • モバイル版UIの改善: チャット履歴を選択した際に、自動的にサイドバーが閉じるように修正します。(現状は手動で閉じる必要があり、操作性が良くありません)
  • 独自ダッシュボードの追加: 複数のDify環境や関連ツールへのリンクをまとめた、簡易的なダッシュボード画面(HTML)を設置し、Basic認証で保護します。

1. フロントエンド(React)の修正

Difyのフロントエンドコードを修正し、モバイルでの挙動を改善します。

サイドバーコンポーネントの修正

編集ファイル:dify/web/app/components/base/chat/chat-with-history/sidebar/index.tsx

チャット切り替え時に、親コンポーネントから渡された「閉じる関数(onClose)」を実行するように変更します。

23行目付近~

type Props = {
  isPanel?: boolean
+ onClose?: () => void
}

- const Sidebar = ({ isPanel }: Props) => {
+ const Sidebar = ({ isPanel, onClose }: Props) => {
  const { t } = useTranslation()
  const {
    appData,
    handleNewConversation,
    pinnedConversationList,
    conversationList,
    currentConversationId,
    handleChangeConversation,
    handlePinConversation,
    handleUnpinConversation,
    conversationRenaming,
    handleRenameConversation,
    handleDeleteConversation,
    sidebarCollapseState,
    handleSidebarCollapse,
    isMobile,
    isResponding,
  } = useChatWithHistoryContext()

52行目付近~

const handleOperate = useCallback((type: string, item: ConversationItem) => {
    if (type === 'pin')
      handlePinConversation(item.id)

    if (type === 'unpin')
      handleUnpinConversation(item.id)

    if (type === 'delete')
      setShowConfirm(item)

    if (type === 'rename')
      setShowRename(item)
  }, [handlePinConversation, handleUnpinConversation])
+ const handleChangeConversationWrapper = useCallback((conversationId: string) => {
+    handleChangeConversation(conversationId)
+    if (onClose)
+      onClose()
+  }, [handleChangeConversation, onClose])
  const handleCancelConfirm = useCallback(() => {
    setShowConfirm(null)
  }, [])

114行目付近~

<div className='h-0 grow space-y-2 overflow-y-auto px-3 pt-4'>
    {/* pinned list */}
    {!!pinnedConversationList.length && (
      <div className='mb-4'>
        <List
          isPin
          title={t('share.chat.pinnedTitle') || ''}
          list={pinnedConversationList}
-         onChangeConversation={handleChangeConversation}
+         onChangeConversation={handleChangeConversationWrapper}
          onOperate={handleOperate}
          currentConversationId={currentConversationId}
        />
      </div>
    )}
    {!!conversationList.length && (
      <List
        title={(pinnedConversationList.length && t('share.chat.unpinnedTitle')) || ''}
        list={conversationList}
-       onChangeConversation={handleChangeConversation}
+       onChangeConversation={handleChangeConversationWrapper}
        onOperate={handleOperate}
        currentConversationId={currentConversationId}
      />
    )}

モバイルヘッダーでの呼び出し修正

編集ファイル:dify/web/app/components/base/chat/chat-with-history/header-in-mobile.tsx

サイドバー呼び出し時に、閉じるための関数を渡します。

104行目付近~

{showSidebar && (
  <div className='fixed inset-0 z-50 flex bg-background-overlay p-1'
    onClick={() => setShowSidebar(false)}
  >
    <div className='flex h-full w-[calc(100vw_-_40px)] rounded-xl bg-components-panel-bg shadow-lg backdrop-blur-sm' onClick={e => e.stopPropagation()}>
-     <Sidebar />
+     <Sidebar isPanel onClose={() => setShowSidebar(false)} />
    </div>
  </div>
)}

2. 独自ダッシュボードの追加

Nginxコンテナを利用して、静的なHTMLファイル(ダッシュボード)を配信する設定を追加します。

HTMLファイルの作成

# ディレクトリ作成 
mkdir -p dify/docker/nginx/html

# dashboard.htmlの中身を作成
nano html/dashboard.html

Nginx設定の修正とBasic認証

ダッシュボードへのアクセス制限(Basic認証)を設定します。

# 認証ツールのインストール 
sudo apt update && 
sudo apt install apache2-utils

パスワードファイルの作成
sudo htpasswd -c dify/docker/nginx/conf.d/.htpasswd <ユーザー名>

Nginxの設定ファイル(dify/docker/nginx/conf.d/default.conf等 ※環境による)に以下を追記します。

ルーティングとBasic認証の追加

location / {
  proxy_pass http://web:3000;
  include proxy.conf;
}
+ location /dashboard {
+   auth_basic "Restricted Access";
+   auth_basic_user_file /etc/nginx/conf.d/.htpasswd;
+   root /usr/share/nginx/html;
+   index dashboard.html;
+   try_files /dashboard.html $uri $uri/ =404;
+ }
+ 
# placeholder for acme challenge location
${ACME_CHALLENGE_LOCATION}

3. Docker環境への反映

修正したフロントエンドコードを反映させるため、Docker Composeの設定を変更し、イメージをビルドし直します。

docker-compose.yamlの修正

デフォルトではDocker Hubのイメージを使用していますが、ローカルのソースコードからビルドするように変更します。

docker-compose.yaml (webサービス部分)

# Frontend web application.
  web:
-  image: langgenius/dify-web:1.2.0
+  build:
+    context: ../web
+    dockerfile: Dockerfile
    restart: always
    environment:
      CONSOLE_API_URL: ${CONSOLE_API_URL:-}
      APP_API_URL: ${APP_API_URL:-}
      SENTRY_DSN: ${WEB_SENTRY_DSN:-}
      NEXT_TELEMETRY_DISABLED: ${NEXT_TELEMETRY_DISABLED:-0}
      TEXT_GENERATION_TIMEOUT_MS: ${TEXT_GENERATION_TIMEOUT_MS:-60000}
      CSP_WHITELIST: ${CSP_WHITELIST:-}
      MARKETPLACE_API_URL: ${MARKETPLACE_API_URL:-https://marketplace.dify.ai}
      MARKETPLACE_URL: ${MARKETPLACE_URL:-https://marketplace.dify.ai}
      TOP_K_MAX_VALUE: ${TOP_K_MAX_VALUE:-}
      INDEXING_MAX_SEGMENTATION_TOKENS_LENGTH: ${INDEXING_MAX_SEGMENTATION_TOKENS_LENGTH:-}
      PM2_INSTANCES: ${PM2_INSTANCES:-2}
      LOOP_NODE_MAX_COUNT: ${LOOP_NODE_MAX_COUNT:-100}
      MAX_TOOLS_NUM: ${MAX_TOOLS_NUM:-10}
      MAX_PARALLEL_LIMIT: ${MAX_PARALLEL_LIMIT:-10}
      MAX_ITERATIONS_NUM: ${MAX_ITERATIONS_NUM:-5}

また、NginxサービスにHTMLファイルをマウントする設定を追加します。

691行目付近~ (nginxサービス部分)

nginx:
  image: nginx:latest
  restart: always
  volumes:
    - ./nginx/nginx.conf.template:/etc/nginx/nginx.conf.template
    - ./nginx/proxy.conf.template:/etc/nginx/proxy.conf.template
    - ./nginx/https.conf.template:/etc/nginx/https.conf.template
    - ./nginx/conf.d:/etc/nginx/conf.d
+   - ./nginx/html:/usr/share/nginx/html
    - ./nginx/docker-entrypoint.sh:/docker-entrypoint-mount.sh
    - ./nginx/ssl:/etc/ssl # cert dir (legacy)
    - ./volumes/certbot/conf/live:/etc/letsencrypt/live # cert dir (with certbot container)
    - ./volumes/certbot/conf:/etc/letsencrypt
    - ./volumes/certbot/www:/var/www/html

ビルドと再起動

設定変更後、コンテナを再ビルドして起動します。

cd dify/docker 
docker compose up -d --build

まとめ

これで、モバイル版での操作性が向上し、管理用のダッシュボードも追加されました。

Difyはオープンソースであるため、このように自社の運用に合わせて柔軟にUI/UXを改善できるのが大きな魅力です。ぜひ、使いやすい環境構築にチャレンジしてみてください。

【推奨】業務システム化に有効なアイテム

生成AIを学ぶ

システム化のパートナー

VPSサーバの選定

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

コメント

コメントする

CAPTCHA


目次