> ## Documentation Index
> Fetch the complete documentation index at: https://auth0.generaltranslation.app/llms.txt
> Use this file to discover all available pages before exploring further.

# Angular アプリケーションにログイン機能を追加する

export const AuthCodeGroup = ({children, dropdown}) => {
  const [processedChildren, setProcessedChildren] = useState(children);
  useEffect(() => {
    let unsubscribe = null;
    function init() {
      unsubscribe = window.autorun(() => {
        const processChildren = node => {
          if (typeof node === "string") {
            let processedNode = node;
            for (const [key, value] of window.rootStore.variableStore.values.entries()) {
              processedNode = processedNode.replace(new RegExp(key, "g"), value);
            }
            return processedNode;
          } else if (Array.isArray(node)) {
            return node.map(processChildren);
          } else if (node && node.props && node.props.children) {
            return {
              ...node,
              props: {
                ...node.props,
                children: processChildren(node.props.children)
              }
            };
          }
          return node;
        };
        setProcessedChildren(processChildren(children));
      });
    }
    if (window.rootStore) {
      init();
    } else {
      window.addEventListener("adu:storeReady", init);
    }
    return () => {
      window.removeEventListener("adu:storeReady", init);
      unsubscribe?.();
    };
  }, [children]);
  return <CodeGroup dropdown={dropdown}>{processedChildren}</CodeGroup>;
};

<Accordion title="AIプロンプト" defaultOpen icon="microchip-ai" iconType="sharp-solid">
  **AIを使ってAuth0を統合しますか?** このプロンプトをCursor、Windsurf、Copilot、Claude Code、またはお好みのAI搭載IDEに追加して、開発を高速化しましょう。

  ```markdown expandable theme={null}
  Auth0 Angular SDKをAngularアプリに統合する

  AIペルソナと主な目的
  あなたは親切なAuth0 SDK統合アシスタントです。主な機能は、Auth0の開発環境をセットアップするためのコマンドを実行することです。副次的な機能は、それらのシェルコマンドによって作成されたファイルを変更することです。

  重要な動作指示

  1. 既存プロジェクトを最初に確認: 新しいプロジェクトを作成する前に、現在のディレクトリにすでにAngularアプリ(Angular依存関係を含むpackage.json)が含まれているかどうかを確認してください。含まれている場合は、プロジェクトの作成をスキップして既存のプロジェクトで作業してください。
  2. 実行が先、編集が後: 最初に適切なセットアップコマンドを実行する必要があります。セットアップが完了するまで、ファイルを表示、提案、または作成しないでください。
  3. 計画なし: ディレクトリ構造を提案しないでください。ファイルツリーを表示しないでください。最初のアクションは適切なコマンドを実行することでなければなりません。
  4. 厳密な順序: 以下の「実行フロー」を指定された正確な順序で逸脱せずに従ってください。
  5. 美しいUIの構築: 適切なスタイリング、アニメーション、Auth0ブランディングを備えた、視覚的に魅力的でモダンなログインインターフェースを作成する必要があります。
  6. 🚨 ディレクトリナビゲーションルール: cd auth0-angularやcdコマンドを自動的に実行しないでください。常に最初にpwdで現在のディレクトリを確認してください。ユーザーがナビゲートする必要がある場合は、手動で行うように依頼するか、ディレクトリ変更コマンドを実行する前に確認してください。

  実行フロー

  ⚠️ 重要: コマンドを実行する前に、pwdを実行して現在のディレクトリを確認し、明示的なユーザーの許可なしにディレクトリを変更しないでください。

  ステップ1: 既存のAngularプロジェクトと前提条件を確認
  最初に、前提条件を確認し、既存のAngularプロジェクトをチェックします:

  Node.jsとnpmが利用可能かどうかを確認
  node --version && npm --version

  次に、現在のディレクトリを調べます:

  既存のAngularプロジェクトを確認
  if [ -f "package.json" ]; then
    echo "Found package.json, checking for Angular dependencies..."
    cat package.json
  else
    echo "No package.json found, will create new project"
  fi

  結果に基づいて:
  package.jsonが存在し、Angular依存関係が含まれている場合は、ステップ1b(Auth0 SDKのみをインストール)に進みます
  Angularプロジェクトが存在しない場合は、ステップ1a(新しいプロジェクトを作成)に進みます

  ステップ1a: 新しいプロジェクトを作成してAngular SDKをインストール
  既存のプロジェクトが存在する場合は、単にSDKをインストールします:
  npm install @auth0/auth0-angular@latest

  それ以外の場合は、新しいプロジェクトを作成してSDKをインストールします:

  ⚠️ 重要: Angular CLIプロジェクトの作成は、サブディレクトリにプロジェクトを作成します。このコマンドを実行した後、続行する前に現在のディレクトリの内容を確認して、実際のプロジェクト構造を判断してください。

  npx @angular/cli@latest new auth0-angular --routing=true --style=css && cd auth0-angular && npm install @auth0/auth0-angular@latest


  ステップ2: ファイルの変更と作成
  ステップ1のコマンドが正常に実行された後、プロジェクトディレクトリ内で以下のファイル操作を実行します。

  🚨 ディレクトリナビゲーションルール:
  1. 明示的なユーザー確認なしにcdコマンドを自動的に実行しないでください
  2. 続行する前に常にpwdで現在のディレクトリを確認してください
  3. 既存のプロジェクトで作業する場合: 現在のディレクトリに留まります
  4. 新しいプロジェクトを作成した場合: ユーザーは最初にauth0-angularディレクトリに手動でナビゲートする必要があります

  2.1: Auth0環境設定のセットアップ

  ⚠️ 重要: 続行する前に、現在のディレクトリを確認してください:
  新しいプロジェクトを作成したばかりの場合: auth0-angularディレクトリ内にいる必要があります
  既存のプロジェクトで作業している場合: プロジェクトのルートディレクトリにいる必要があります
  cd auth0-angularコマンドを実行しないでください - 最初に正しいディレクトリにナビゲートしてください

  ステップ2.1a: プロジェクトディレクトリにナビゲート(必要な場合)してAuth0をセットアップ:

  新しいプロジェクトを作成し、まだauth0-angular内にいない場合にのみ実行してください:
  cd auth0-angular

  次に、お使いのOSの環境セットアップコマンドを実行します:

  ⚠️ 重要なディレクトリ確認ステップ:
  Auth0 CLIセットアップコマンドを実行する前に、以下を実行する必要があります:

  pwd && ls -la

  これにより、メインディレクトリまたはサブディレクトリのどちらにいるか、プロジェクトが現在のディレクトリまたは新しいサブディレクトリに作成されたかどうかを理解できます。

  MacOSの場合、以下のコマンドを実行します:
  AUTH0_APP_NAME="My Angular App" && brew tap auth0/auth0-cli && brew install auth0 && auth0 login --no-input && auth0 apps create -n "${AUTH0_APP_NAME}" -t spa -c http://localhost:4200 -l http://localhost:4200 -o http://localhost:4200 --json > auth0-app-details.json && CLIENT_ID=$(jq -r '.client_id' auth0-app-details.json) && DOMAIN=$(auth0 tenants list --json | jq -r '.[] | select(.active == true) | .name') && mkdir -p src/environments && echo "export const environment = { production: false, auth0: { domain: '${DOMAIN}', clientId: '${CLIENT_ID}' } };" > src/environments/environment.ts && rm auth0-app-details.json && echo "Environment file created at src/environments/environment.ts with your Auth0 details:" && cat src/environments/environment.ts

  Windowsの場合、以下のコマンドを実行します:
  $AppName = "My Angular App"; winget install Auth0.CLI; auth0 login --no-input; auth0 apps create -n "$AppName" -t spa -c http://localhost:4200 -l http://localhost:4200 -o http://localhost:4200 --json | Set-Content -Path auth0-app-details.json; $ClientId = (Get-Content -Raw auth0-app-details.json | ConvertFrom-Json).client_id; $Domain = (auth0 tenants list --json | ConvertFrom-Json | Where-Object { $_.active -eq $true }).name; New-Item -ItemType Directory -Force -Path "src\environments"; Set-Content -Path "src\environments\environment.ts" -Value "export const environment = { production: false, auth0: { domain: '$Domain', clientId: '$ClientId' } };"; Remove-Item auth0-app-details.json; Write-Output "Environment file created at src\environments\environment.ts with your Auth0 details:"; Get-Content "src\environments\environment.ts"


  ステップ2.1b: 手動環境テンプレートの作成(自動セットアップが失敗した場合)

  mkdir -p src/environments && cat > src/environments/environment.ts << 'EOF'
  // Auth0設定 - これらの値を更新してください
  export const environment = {
    production: false,
    auth0: {
      domain: 'your-auth0-domain.auth0.com',
      clientId: 'your-auth0-client-id'
    }
  };
  EOF

  ステップ2.1c: 手動セットアップ手順の表示

  echo "📋 手動セットアップが必要です:"
  echo "1. https://manage.auth0.com/dashboard/ にアクセスしてください"
  echo "2. 「アプリケーションを作成」→ シングルページアプリケーション をクリックしてください"
  echo "3. 許可されたコールバックURLを設定: http://localhost:4200"
  echo "4. 許可されたログアウトURLを設定: http://localhost:4200"
  echo "5. 許可されたWebオリジンを設定: http://localhost:4200"
  echo "6. ドメインとクライアントIDでsrc/environments/environment.tsファイルを更新してください"

  2.2: main.tsでAuth0モジュールを設定
  src/main.tsの内容全体を置き換えます:

  import { bootstrapApplication } from '@angular/platform-browser';
  import { appConfig } from './app/app.config';
  import { provideAuth0 } from '@auth0/auth0-angular';
  import { mergeApplicationConfig } from '@angular/core';
  import { environment } from './environments/environment';
  import { AppComponent } from './app/app.component';

  // Auth0設定を検証
  if (!environment.auth0.domain || !environment.auth0.clientId) {
    console.error("Auth0設定が見つかりません。environment.tsファイルを確認してください。");
    console.error("必要な環境変数:");
    console.error("- auth0.domain");
    console.error("- auth0.clientId");
    throw new Error("Auth0ドメインとクライアントIDはenvironment.tsファイルに設定する必要があります");
  }

  // ドメイン形式を検証
  if (!environment.auth0.domain.includes('.auth0.com') && !environment.auth0.domain.includes('.us.auth0.com') && !environment.auth0.domain.includes('.eu.auth0.com') && !environment.auth0.domain.includes('.au.auth0.com')) {
    console.warn("Auth0ドメイン形式が正しくない可能性があります。期待される形式: your-domain.auth0.com");
  }

  const auth0Config = mergeApplicationConfig(appConfig, {
    providers: [
      provideAuth0({
        domain: environment.auth0.domain,
        clientId: environment.auth0.clientId,
        authorizationParams: {
          redirect_uri: window.location.origin
        }
      })
    ]
  });

  bootstrapApplication(AppComponent, auth0Config).catch((err) =>
    console.error(err)
  );

  2.3: コンポーネントディレクトリ構造の作成

  mkdir -p src/app/components

  2.4: LoginButtonコンポーネントの作成
  src/app/components/login-button.component.tsを作成します:

  import { Component, inject } from '@angular/core';
  import { AuthService } from '@auth0/auth0-angular';

  @Component({
    selector: 'app-login-button',
    standalone: true,
    template: `
      <button 
        (click)="loginWithRedirect()" 
        class="button login"
      >
        ログイン
      </button>
    `
  })
  export class LoginButtonComponent {
    private auth = inject(AuthService);

    loginWithRedirect(): void {
      this.auth.loginWithRedirect();
    }
  }

  2.5: LogoutButtonコンポーネントの作成
  src/app/components/logout-button.component.tsを作成します:

  import { Component, inject } from '@angular/core';
  import { AuthService } from '@auth0/auth0-angular';

  @Component({
    selector: 'app-logout-button',
    standalone: true,
    template: `
      <button
        (click)="logout()"
        class="button logout"
      >
        ログアウト
      </button>
    `
  })
  export class LogoutButtonComponent {
    private auth = inject(AuthService);

    logout(): void {
      this.auth.logout({ 
        logoutParams: { 
          returnTo: window.location.origin 
        } 
      });
    }
  }

  2.6: プロファイルコンポーネントの作成
  src/app/components/profile.component.ts を作成します:

  import { Component, inject } from '@angular/core';
  import { AuthService } from '@auth0/auth0-angular';
  import { CommonModule } from '@angular/common';

  @Component({
    selector: 'app-profile',
    standalone: true,
    imports: [CommonModule],
    template: `
      @if (auth.isLoading$ | async) {
        <div class="loading-text">プロファイルを読み込んでいます...</div>
      }
      
      @if ((auth.isAuthenticated$ | async) && (auth.user$ | async); as user) {
        <div style="display: flex; flex-direction: column; align-items: center; gap: 1rem;">
          @if (user.picture) {
            <img 
              [src]="user.picture" 
              [alt]="user.name || 'ユーザー'"
              class="profile-picture"
              style="
                width: 110px; 
                height: 110px; 
                border-radius: 50%; 
                object-fit: cover;
                border: 3px solid #63b3ed;
              "
            />
          }
          <div style="text-align: center;">
            <div 
              class="profile-name" 
              style="
                font-size: 2rem; 
                font-weight: 600; 
                color: #f7fafc; 
                margin-bottom: 0.5rem;
              "
            >
              {{ user.name }}
            </div>
            <div 
              class="profile-email" 
              style="
                font-size: 1.15rem; 
                color: #a0aec0;
              "
            >
              {{ user.email }}
            </div>
          </div>
        </div>
      }
    `
  })
  export class ProfileComponent {
    protected auth = inject(AuthService);
  }

  2.7: 美しいUIでAppコンポーネントを更新
  src/app/app.component.ts の内容全体を置き換えます:

  import { Component, inject } from '@angular/core';
  import { AuthService } from '@auth0/auth0-angular';
  import { CommonModule } from '@angular/common';
  import { LoginButtonComponent } from './components/login-button.component';
  import { LogoutButtonComponent } from './components/logout-button.component';
  import { ProfileComponent } from './components/profile.component';

  @Component({
    selector: 'app-root',
    standalone: true,
    imports: [CommonModule, LoginButtonComponent, LogoutButtonComponent, ProfileComponent],
    template: `
      <div class="app-container">
        <!-- 読み込み状態 -->
        @if (auth.isLoading$ | async) {
          <div class="loading-state">
            <div class="loading-text">読み込み中...</div>
          </div>
        }

        <!-- エラー状態 -->
        @if (auth.error$ | async; as error) {
          <div class="error-state">
            <div class="error-title">エラーが発生しました!</div>
            <div class="error-message">問題が発生しました</div>
            <div class="error-sub-message">{{ error.message }}</div>
          </div>
        }

        <!-- メインコンテンツ -->
        @if (!(auth.isLoading$ | async) && !(auth.error$ | async)) {
          <div class="main-card-wrapper">
            <img 
              src="https://cdn.auth0.com/quantum-assets/dist/latest/logos/auth0/auth0-lockup-en-ondark.png" 
              alt="Auth0 Logo" 
              class="auth0-logo"
            />
            <h1 class="main-title">Sample0へようこそ</h1>
            
            <!-- 認証済み状態 -->
            @if (auth.isAuthenticated$ | async) {
              <div class="logged-in-section">
                <div class="logged-in-message">✅ 認証に成功しました!</div>
                <h2 class="profile-section-title">プロファイル</h2>
                <div class="profile-card">
                  <app-profile />
                </div>
                <app-logout-button />
              </div>
            } @else {
              <!-- 未認証状態 -->
              <div class="action-card">
                <p class="action-text">アカウントにサインインして開始してください</p>
                <app-login-button />
              </div>
            }
          </div>
        }
      </div>
    `,
    styles: []
  })
  export class AppComponent {
    protected auth = inject(AuthService);
  }

  2.8: 美しいモダンなCSSスタイリングの追加
  src/styles.css の内容全体を、以下のモダンなAuth0ブランドのスタイリングに置き換えます:

  ⚠️ CSSファイル置き換え戦略:
  既存の styles.css ファイルが大きい、または形式が正しくない場合は、まず新しい一時的なCSSファイル(例: styles-new.css)を作成してから、mv src/styles-new.css src/styles.css のようなターミナルコマンドを使用して元のファイルを置き換えることで、ファイルの破損を回避してください。

  @import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap');

  body {
    margin: 0;
    font-family: 'Inter', sans-serif;
    background-color: #1a1e27;
    min-height: 100vh;
    display: flex;
    justify-content: center;
    align-items: center;
    color: #e2e8f0;
    overflow: hidden;
  }

  #root {
    width: 100%;
    height: 100%;
    display: flex;
    justify-content: center;
    align-items: center;
  }

  .app-container {
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    min-height: 100vh;
    width: 100%;
    padding: 1rem;
    box-sizing: border-box;
  }

  .loading-state, .error-state {
    background-color: #2d313c;
    border-radius: 15px;
    box-shadow: 0 15px 40px rgba(0, 0, 0, 0.4);
    padding: 3rem;
    text-align: center;
  }

  .loading-text {
    font-size: 1.8rem;
    font-weight: 500;
    color: #a0aec0;
    animation: pulse 1.5s infinite ease-in-out;
  }

  .error-state {
    background-color: #c53030;
    color: #fff;
  }

  .error-title {
    font-size: 2.8rem;
    font-weight: 700;
    margin-bottom: 0.5rem;
  }

  .error-message {
    font-size: 1.3rem;
    margin-bottom: 0.5rem;
  }

  .error-sub-message {
    font-size: 1rem;
    opacity: 0.8;
  }

  .main-card-wrapper {
    background-color: #262a33;
    border-radius: 20px;
    box-shadow: 0 20px 60px rgba(0, 0, 0, 0.6), 0 0 0 1px rgba(255, 255, 255, 0.05);
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 2rem;
    padding: 3rem;
    max-width: 500px;
    width: 90%;
    animation: fadeInScale 0.8s ease-out forwards;
  }

  .auth0-logo {
    width: 160px;
    margin-bottom: 1.5rem;
    opacity: 0;
    animation: slideInDown 1s ease-out forwards 0.2s;
  }

  .main-title {
    font-size: 2.8rem;
    font-weight: 700;
    color: #f7fafc;
    text-align: center;
    margin-bottom: 1rem;
    text-shadow: 0 4px 10px rgba(0, 0, 0, 0.3);
    opacity: 0;
    animation: fadeIn 1s ease-out forwards 0.4s;
  }

  .action-card {
    background-color: #2d313c;
    border-radius: 15px;
    box-shadow: inset 0 2px 5px rgba(0, 0, 0, 0.3), 0 5px 15px rgba(0, 0, 0, 0.3);
    padding: 2.5rem;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 1.8rem;
    width: calc(100% - 2rem);
    opacity: 0;
    animation: fadeIn 1s ease-out forwards 0.6s;
  }

  .action-text {
    font-size: 1.25rem;
    color: #cbd5e0;
    text-align: center;
    line-height: 1.6;
    font-weight: 400;
  }

  .button {
    padding: 1.1rem 2.8rem;
    font-size: 1.2rem;
    font-weight: 600;
    border-radius: 10px;
    border: none;
    cursor: pointer;
    transition: all 0.3s cubic-bezier(0.25, 0.8, 0.25, 1);
    box-shadow: 0 8px 20px rgba(0, 0, 0, 0.4);
    text-transform: uppercase;
    letter-spacing: 0.08em;
    outline: none;
  }

  .button:focus {
    box-shadow: 0 0 0 4px rgba(99, 179, 237, 0.5);
  }

  .button.login {
    background-color: #63b3ed;
    color: #1a1e27;
  }

  .button.login:hover {
    background-color: #4299e1;
    transform: translateY(-5px) scale(1.03);
    box-shadow: 0 12px 25px rgba(0, 0, 0, 0.5);
  }

  .button.logout {
    background-color: #fc8181;
    color: #1a1e27;
  }

  .button.logout:hover {
    background-color: #e53e3e;
    transform: translateY(-5px) scale(1.03);
    box-shadow: 0 12px 25px rgba(0, 0, 0, 0.5);
  }

  .logged-in-section {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 1.5rem;
    width: 100%;
  }

  .logged-in-message {
    font-size: 1.5rem;
    color: #68d391;
    font-weight: 600;
    animation: fadeIn 1s ease-out forwards 0.8s;
  }

  .profile-section-title {
    font-size: 2.2rem;
    animation: slideInUp 1s ease-out forwards 1s;
  }

  .profile-card {
    padding: 2.2rem;
    animation: scaleIn 0.8s ease-out forwards 1.2s;
  }

  .profile-picture {
    width: 110px;
    transition: transform 0.3s ease-in-out;
  }

  .profile-picture:hover {
    transform: scale(1.05);
  }

  .profile-name {
    font-size: 2rem;
    margin-top: 0.5rem;
  }

  .profile-email {
    font-size: 1.15rem;
    text-align: center;
  }

  @keyframes fadeIn {
    from { opacity: 0; }
    to { opacity: 1; }
  }

  @keyframes fadeInScale {
    from { opacity: 0; transform: scale(0.95); }
    to { opacity: 1; transform: scale(1); }
  }

  @keyframes slideInDown {
    from { opacity: 0; transform: translateY(-70px); }
    to { opacity: 1; transform: translateY(0); }
  }

  @keyframes slideInUp {
    from { opacity: 0; transform: translateY(50px); }
    to { opacity: 1; transform: translateY(0); }
  }

  @keyframes pulse {
    0%, 100% { opacity: 1; }
    50% { opacity: 0.6; }
  }

  @keyframes scaleIn {
    from { opacity: 0; transform: scale(0.8); }
    to { opacity: 1; transform: scale(1); }
  }

  @media (max-width: 600px) {
    .main-card-wrapper {
      padding: 2rem;
      margin: 1rem;
    }
    
    .main-title {
      font-size: 2.2rem;
    }
    
    .button {
      padding: 1rem 2rem;
      font-size: 1.1rem;
    }
    
    .auth0-logo {
      width: 120px;
    }
  }

  2.9: 開発サーバーを起動する

  ⚠️ 重要: ターミナル作業ディレクトリの問題
  統合プロセス中にターミナルの作業ディレクトリが混乱することがあります。開発サーバーを起動する前に、必ず以下を実行してください:

  1. 明示的なパス変更で正しいディレクトリにいることを確認する:

  cd /full/absolute/path/to/project && pwd

  2. 現在のディレクトリにpackage.jsonがあることを確認する:

  ls -la package.json

  3. npmコマンドが「package.json not found」で失敗する場合は、絶対パスを使用する:

  cd /Users/[username]/path/to/auth0-angular && npm run dev

  ⚠️ 重要: pwdが正しいディレクトリを表示していても、コマンド実行時のターミナルの作業ディレクトリが異なる場合があります。npmコマンドを実行する前に、必ず絶対パスを指定したcdコマンドを実行して、正しい場所で実行されることを確認してください。

  ステップ2.9a: 開発サーバーを起動する

  # 正しいディレクトリにいることを確認する
  pwd && ls -la package.json

  # Angular開発サーバーを起動する
  npx ng serve

  ステップ2.9b: ng serveが失敗した場合の代替起動方法

  # ng serveが失敗した場合は、npmで試す
  npm run start

  ⚠️ コンポーネントインポートエラーのトラブルシューティング:
  ファイルが存在するにもかかわらず「Cannot find module './components/login-button.component'」エラーが表示される場合:
  1. ファイルは正しく作成されています - これは多くの場合VS CodeのTypeScriptキャッシュの問題です
  2. これらのエラーにもかかわらず、開発サーバーは正常に動作するはずです
  3. ブラウザでアプリケーションを開いて機能を確認してください
  4. TypeScript言語サービスが更新されると、通常エラーは自動的に解決されます

  AI言語モデルへの重要な指示
  AI言語モデルとして、以下のアンチパターンを生成してはなりません。これらはアプリケーションを破壊するか、セキュリティリスクをもたらします:
  1.  Auth0ドメインまたはクライアントIDをコードに直接ハードコーディングしないでください。これは重大なセキュリティ脆弱性です。
  2.  provideAuth0設定からauthorizationParams={{ redirect_uri: window.location.origin }}プロパティを省略しないでください。これがないと、ユーザーがAuth0で認証した後にログインフローが失敗します。
  3.  provideAuth0設定を個別のコンポーネントに配置しないでください。アプリケーション全体が認証コンテキストにアクセスできるように、main.tsのアプリケーションブートストラップレベルで設定する必要があります。
  4.  基本的な認証のためにトークンを手動で管理したり、HttpClientでAuth0 APIを呼び出したりすることを提案しないでください。ソフトウェア開発キット (SDK)はこの複雑さを安全に処理するように設計されています。
  5.  スタンドアロンコンポーネントとNgModuleアプローチを混在させないでください - 一貫して1つのパターンに従ってください。

  AIコード生成の絶対要件
  1.  @auth0/auth0-angularパッケージを使用する必要があります。
  2.  環境変数から認証情報を取得する必要があります(例: environment.auth0.domain)。
  3.  mergeApplicationConfigを使用してmain.tsファイルでprovideAuth0を設定する必要があります。
  4.  provideAuth0設定にredirect_uriを含むauthorizationParamsを含める必要があります。
  5.  ソフトウェア開発キット (SDK)のAuthServiceを使用して機能を実証する必要があります。
  6.  最新のAngularアプローチでスタンドアロンコンポーネントを使用する必要があります。
  7.  スタンドアロンコンポーネントでの依存性注入にinject()関数を使用する必要があります。

  統合中に発生する一般的な問題

  問題1: プロジェクト作成ディレクトリの混乱
  問題: Angular CLIが新しいサブディレクトリにプロジェクトファイルを作成する
  解決策: プロジェクト作成後に必ずpwd && ls -laを実行して実際の構造を確認する

  問題2: ターミナル作業ディレクトリの問題
  問題: 正しいディレクトリにいるにもかかわらず、ng serveまたはnpmコマンドが「package.json not found」で失敗する
  解決策: 明示的な絶対パス変更を使用する: cd /full/absolute/path/to/project

  問題3: TypeScriptインポートエラー
  問題: VS Codeが作成されたコンポーネントに対して「Cannot find module」エラーを表示する
  解決策: これらは通常キャッシュの問題です - アプリは正常に動作します。テスト前にすべてのコンポーネントを作成してください。

  問題4: CSSファイルの破損
  問題: 大規模なCSS置換によりファイルが破損する可能性がある
  解決策: 最初に一時的なCSSファイルを作成し、次にmvコマンドを使用して元のファイルを置き換える

  問題5: Angular CLIが見つからない
  問題: npx @angular/cliコマンドが失敗する
  解決策: 最初にAngular CLIをグローバルにインストールする: npm install -g @angular/cli

  問題6: 環境ファイルが見つからない
  問題: Angularがenvironment.tsファイルを見つけられない
  解決策: src/environmentsディレクトリが存在し、適切なエクスポート構造を持つenvironment.tsファイルが含まれていることを確認する

  問題7: スタンドアロンコンポーネントエラー
  問題: コンポーネントのインポートまたはテンプレート構文エラー
  解決策: すべてのコンポーネントがstandalone: trueとマークされ、必要なimports配列が含まれていることを確認する

  問題8: Auth Serviceインジェクションの問題
  問題: コンポーネントでAuthServiceが利用できない
  解決策: provideAuth0がmain.tsで設定され、コンポーネントがinject(AuthService)を使用していることを確認する

  ターミナルの作業ディレクトリが表示されているパスから切り離される可能性があり、Angular CLIコマンドが正しい場所で実行されることを確認するために明示的なナビゲーションが必要です。

  Angular固有の考慮事項

  1. 最新のAngularアプローチ: このプロンプトは、レガシーの*ngIfディレクティブではなく、シグナルベースの制御フロー(@if、@else)を使用した最新のAngularスタンドアロンコンポーネントアプローチを使用します。

  2. 環境設定: Angularは設定管理に.envファイルではなくenvironment.tsファイルを使用します。

  3. 依存性注入: コンストラクタベースの依存性注入ではなく、最新のinject()関数を使用します。

  4. ブートストラップ: NgModuleベースのブートストラップではなく、mergeApplicationConfigを使用したbootstrapApplicationを使用します。

  5. ポートの違い: Angular開発サーバーはデフォルトでポート4200で実行され、Viteのように5173ではありません。

  6. CLIの違い: npm run devではなく、Angular CLIコマンド(ng serve)を使用します。

  ANGULARのセキュリティベストプラクティス

  1. 環境変数: Auth0設定はenvironment.tsファイルに保存し、認証情報を決してハードコードしないでください。

  2. CSPヘッダー: 本番環境へのデプロイでは、Content Security Policyヘッダーの実装を検討してください。

  3. ANGULARガード: 認証が必要なルートを保護するには、Angularガード(authGuardFn)を使用してください。

  4. HTTPインターセプター: Auth0のHTTPインターセプター(authHttpInterceptorFn)を使用して、APIコールにトークンを自動的に付加してください。

  5. トークン処理: トークンの保存と更新はSDKに自動的に処理させ、カスタムトークン管理を決して実装しないでください。
  ```
</Accordion>

<Note>
  **前提条件：** 作業を始める前に、次のツールがインストールされていることを確認してください。

  * **[Node.js](https://nodejs.org/en/download)** 20 LTS 以上
  * **[npm](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm)** 10 以上、または **[yarn](https://classic.yarnpkg.com/lang/en/docs/install/)** 1.22 以上、または **[pnpm](https://pnpm.io/installation)** 8 以上
  * **[jq](https://jqlang.org/)** - Auth0 CLI のセットアップに必須です

  **Angular のバージョン互換性：** このクイックスタートは Angular CLI を使用する **Angular 18.x 以降** で動作します。より古いバージョンの Angular を使用する場合は、Auth0 Angular ソフトウェア開発キット (SDK) v2 を使用してください。
</Note>

<div id="get-started">
  ## はじめに
</div>

このクイックスタートでは、Angular アプリケーションに Auth0 認証を追加する方法を説明します。Angular の依存性注入システムと Auth0 Angular ソフトウェア開発キット (SDK) を使用して、ログインおよびログアウト機能を備えた安全なシングルページ アプリケーション (SPA) を構築します。

<Steps>
  <Step title="新しいプロジェクトを作成する" stepNumber={1}>
    このクイックスタート用の新しい Angular プロジェクトを作成します

    ```shellscript theme={null}
    npx @angular/cli@latest new auth0-angular --routing=true --style=css
    ```

    プロジェクトを開く

    ```shellscript theme={null}
    cd auth0-angular
    ```
  </Step>

  <Step title="Auth0 Angular ソフトウェア開発キット (SDK) のインストール" stepNumber={2}>
    ```shellscript theme={null}
    npm install @auth0/auth0-angular && npm install
    ```
  </Step>

  <Step title="Auth0 アプリケーションの設定" stepNumber={3}>
    次に、Auth0 テナント上に新しいアプリを作成し、環境変数をプロジェクトに追加します。

    これは、CLI コマンドを実行して自動的に行うか、Dashboard から手動で行うかを選択できます。

    <Tabs>
      <Tab title="CLI">
        プロジェクトのルートディレクトリで次のシェルコマンドを実行して、Auth0 アプリを作成し、環境ファイルを生成します。

        <AuthCodeGroup>
          ```shellscript Mac theme={null}
          AUTH0_APP_NAME="My Angular App" && brew tap auth0/auth0-cli && brew install auth0 && auth0 login --no-input && auth0 apps create -n "${AUTH0_APP_NAME}" -t spa -c http://localhost:4200 -l http://localhost:4200 -o http://localhost:4200 --json > auth0-app-details.json && CLIENT_ID=$(jq -r '.client_id' auth0-app-details.json) && DOMAIN=$(auth0 tenants list --json | jq -r '.[] | select(.active == true) | .name') && mkdir -p src/environments && echo "export const environment = { production: false, auth0: { domain: '${DOMAIN}', clientId: '${CLIENT_ID}' } };" > src/environments/environment.ts && rm auth0-app-details.json && echo "Environment file created at src/environments/environment.ts with your Auth0 details:" && cat src/environments/environment.ts
          ```

          ```shellscript Windows theme={null}
          $AppName = "My Angular App"; winget install Auth0.CLI; auth0 login --no-input; auth0 apps create -n "$AppName" -t spa -c http://localhost:4200 -l http://localhost:4200 -o http://localhost:4200 --json | Set-Content -Path auth0-app-details.json; $ClientId = (Get-Content -Raw auth0-app-details.json | ConvertFrom-Json).client_id; $Domain = (auth0 tenants list --json | ConvertFrom-Json | Where-Object { $_.active -eq $true }).name; New-Item -ItemType Directory -Force -Path "src\environments"; Set-Content -Path "src\environments\environment.ts" -Value "export const environment = { production: false, auth0: { domain: '$Domain', clientId: '$ClientId' } };"; Remove-Item auth0-app-details.json; Write-Output "Environment file created at src\environments\environment.ts with your Auth0 details:"; Get-Content "src\environments\environment.ts"
          ```
        </AuthCodeGroup>
      </Tab>

      <Tab title="Dashboard">
        作業を始める前に、プロジェクトに環境ファイルを作成します。

        ```typescript src/environments/environment.ts theme={null}
        export const environment = {
          production: false,
          auth0: {
            domain: 'YOUR_AUTH0_APP_DOMAIN',
            clientId: 'YOUR_AUTH0_APP_CLIENT_ID'
          }
        };
        ```

        1. [Auth0 Dashboard](https://manage.auth0.com/dashboard/) に移動します
        2. **Applications** > **Applications** > **Create Application** をクリックします
        3. ポップアップでアプリの名前を入力し、アプリのタイプとして `Single Page Web Application` を選択して **Create** をクリックします
        4. Application Details ページの **Settings** タブに切り替えます
        5. Dashboard に表示されている **Domain** と **Client ID** の値で、`src/environments/environment.ts` ファイル内の `YOUR_AUTH0_APP_DOMAIN` と `YOUR_AUTH0_APP_CLIENT_ID` を置き換えます

        最後に、Application Details ページの **Settings** タブで、次の URL を設定します。

        **許可されたコールバックURL（Allowed Callback URLs）：**

        ```
        http://localhost:4200
        ```

        **許可されたログアウトURL（Allowed Logout URLs）：**

        ```
        http://localhost:4200
        ```

        **Allowed Web Origins：**

        ```
        http://localhost:4200
        ```

        <Info>
          **Allowed Callback URLs** は、認証後にユーザーを安全にアプリケーションへ戻すための重要なセキュリティ対策です。一致する URL がない場合、ログイン処理は失敗し、ユーザーはアプリにアクセスできず、代わりに Auth0 のエラーページでブロックされます。

          **Allowed Logout URLs** は、サインアウト時にシームレスなユーザー体験を提供するために不可欠です。一致する URL がない場合、ログアウト後にユーザーはアプリケーションへリダイレクトされず、汎用的な Auth0 のページに留まることになります。

          **Allowed Web Origins** は、サイレント認証にとって非常に重要です。これを設定していない場合、ユーザーはページを更新したり、後でアプリに戻ったときにログアウトされてしまいます。
        </Info>
      </Tab>
    </Tabs>
  </Step>

  <Step title="Auth0 モジュールを設定する" stepNumber={4}>
    CLI スクリプトによって環境ファイルはすでに作成されています。次に、アプリで Auth0 モジュールを設定します。

    ```typescript src/main.ts {3,4,5,9-15} lines theme={null}
    import { bootstrapApplication } from '@angular/platform-browser';
    import { appConfig } from './app/app.config';
    import { provideAuth0 } from '@auth0/auth0-angular';
    import { mergeApplicationConfig } from '@angular/core';
    import { environment } from './environments/environment';
    import { AppComponent } from './app/app.component';

    const auth0Config = mergeApplicationConfig(appConfig, {
      providers: [
        provideAuth0({
          domain: environment.auth0.domain,
          clientId: environment.auth0.clientId,
          authorizationParams: {
            redirect_uri: window.location.origin
          }
        })
      ]
    });

    bootstrapApplication(AppComponent, auth0Config).catch((err) =>
      console.error(err)
    );
    ```

    <Note>
      ダッシュボードで Auth0 アプリを手動で設定した場合は、ダッシュボードに表示されているドメインとクライアントID を使用して `src/environments/environment.ts` ファイルを作成してください。
    </Note>
  </Step>

  <Step title="ログイン、ログアウト、プロファイルの各コンポーネントを作成する" stepNumber={5}>
    より細かく制御するために、コンポーネントファイルを手動で作成する

    ```shellscript theme={null}
    mkdir -p src/app/components && touch src/app/components/login-button.component.ts && touch src/app/components/logout-button.component.ts && touch src/app/components/profile.component.ts
    ```

    各コンポーネントに以下のコードを追加してください:

    <AuthCodeGroup>
      ```typescript src/app/components/login-button.component.ts expandable lines theme={null}
      import { Component, inject } from '@angular/core';
      import { AuthService } from '@auth0/auth0-angular';

      @Component({
        selector: 'app-login-button',
        standalone: true,
        template: `
          <button 
            (click)="loginWithRedirect()" 
            class="button login"
          >
            Log In
          </button>
        `
      })
      export class LoginButtonComponent {
        private auth = inject(AuthService);

        loginWithRedirect(): void {
          this.auth.loginWithRedirect();
        }
      }
      ```

      ```typescript src/app/components/logout-button.component.ts expandable lines theme={null}
      import { Component, inject } from '@angular/core';
      import { AuthService } from '@auth0/auth0-angular';

      @Component({
        selector: 'app-logout-button',
        standalone: true,
        template: `
          <button
            (click)="logout()"
            class="button logout"
          >
            Log Out
          </button>
        `
      })
      export class LogoutButtonComponent {
        private auth = inject(AuthService);

        logout(): void {
          this.auth.logout({ 
            logoutParams: { 
              returnTo: window.location.origin 
            } 
          });
        }
      }
      ```

      ```typescript src/app/components/profile.component.ts expandable lines theme={null}
      import { Component, inject } from '@angular/core';
      import { AuthService } from '@auth0/auth0-angular';
      import { CommonModule } from '@angular/common';

      @Component({
        selector: 'app-profile',
        standalone: true,
        imports: [CommonModule],
        template: `
          @if (auth.isLoading$ | async) {
            <div class="loading-text">プロファイルを読み込み中...</div>
          }
          
          @if ((auth.isAuthenticated$ | async) && (auth.user$ | async); as user) {
            <div style="display: flex; flex-direction: column; align-items: center; gap: 1rem;">
              @if (user.picture) {
                <img 
                  [src]="user.picture" 
                  [alt]="user.name || 'ユーザー'"
                  class="profile-picture"
                  style="
                    width: 110px; 
                    height: 110px; 
                    border-radius: 50%; 
                    object-fit: cover;
                    border: 3px solid #63b3ed;
                  "
                />
              }
              <div style="text-align: center;">
                <div 
                  class="profile-name" 
                  style="
                    font-size: 2rem; 
                    font-weight: 600; 
                    color: #f7fafc; 
                    margin-bottom: 0.5rem;
                  "
                >
                  {{ user.name }}
                </div>
                <div 
                  class="profile-email" 
                  style="
                    font-size: 1.15rem; 
                    color: #a0aec0;
                  "
                >
                  {{ user.email }}
                </div>
              </div>
            </div>
          }
        `
      })
      export class ProfileComponent {
        protected auth = inject(AuthService);
      }
      ```
    </AuthCodeGroup>

    次に、メインのAppコンポーネントを更新してスタイリングを追加します:

    <Tabs>
      <Tab title="App コンポーネント">
        `src/app/app.component.ts` の内容を次の内容に置き換えてください:

        ```typescript src/app/app.ts expandable lines theme={null}
        import { Component, inject } from '@angular/core';
        import { AuthService } from '@auth0/auth0-angular';
        import { CommonModule } from '@angular/common';
        import { LoginButtonComponent } from './components/login-button.component';
        import { LogoutButtonComponent } from './components/logout-button.component';
        import { ProfileComponent } from './components/profile.component';

        @Component({
          selector: 'app-root',
          standalone: true,
          imports: [CommonModule, LoginButtonComponent, LogoutButtonComponent, ProfileComponent],
          template: `
            <div class="app-container">
              <!-- 読み込み状態 -->
              @if (auth.isLoading$ | async) {
                <div class="loading-state">
                  <div class="loading-text">読み込み中...</div>
                </div>
              }

              <!-- エラー状態 -->
              @if (auth.error$ | async; as error) {
                <div class="error-state">
                  <div class="error-title">エラーが発生しました</div>
                  <div class="error-message">問題が発生しました</div>
                  <div class="error-sub-message">{{ error.message }}</div>
                </div>
              }

              <!-- メインコンテンツ -->
              @if (!(auth.isLoading$ | async) && !(auth.error$ | async)) {
                <div class="main-card-wrapper">
                  <img 
                    src="https://cdn.auth0.com/quantum-assets/dist/latest/logos/auth0/auth0-lockup-en-ondark.png" 
                    alt="Auth0 ロゴ" 
                    class="auth0-logo"
                  />
                  <h1 class="main-title">Sample0 へようこそ</h1>
                  
                  <!-- 認証済み状態 -->
                  @if (auth.isAuthenticated$ | async) {
                    <div class="logged-in-section">
                      <div class="logged-in-message">✅ 認証に成功しました!</div>
                      <h2 class="profile-section-title">プロファイル</h2>
                      <div class="profile-card">
                        <app-profile />
                      </div>
                      <app-logout-button />
                    </div>
                  } @else {
                    <!-- 未認証状態 -->
                    <div class="action-card">
                      <p class="action-text">アカウントにログインして開始してください</p>
                      <app-login-button />
                    </div>
                  }
                </div>
              }
            </div>
          `,
          styles: []
        })
        export class AppComponent {
          protected auth = inject(AuthService);
        }
        ```
      </Tab>

      <Tab title="グローバル スタイル">
        `src/styles.css` にスタイルを追加します:

        ```css src/styles.css expandable lines theme={null}
        @import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap');

        body {
          margin: 0;
          font-family: 'Inter', sans-serif;
          background-color: #1a1e27;
          min-height: 100vh;
          display: flex;
          justify-content: center;
          align-items: center;
          color: #e2e8f0;
          overflow: hidden;
        }

        #root {
          width: 100%;
          height: 100%;
          display: flex;
          justify-content: center;
          align-items: center;
        }

        .app-container {
          display: flex;
          flex-direction: column;
          justify-content: center;
          align-items: center;
          min-height: 100vh;
          width: 100%;
          padding: 1rem;
          box-sizing: border-box;
        }

        .loading-state, .error-state {
          background-color: #2d313c;
          border-radius: 15px;
          box-shadow: 0 15px 40px rgba(0, 0, 0, 0.4);
          padding: 3rem;
          text-align: center;
        }

        .loading-text {
          font-size: 1.8rem;
          font-weight: 500;
          color: #a0aec0;
          animation: pulse 1.5s infinite ease-in-out;
        }

        .error-state {
          background-color: #c53030;
          color: #fff;
        }

        .error-title {
          font-size: 2.8rem;
          font-weight: 700;
          margin-bottom: 0.5rem;
        }

        .error-message {
          font-size: 1.3rem;
          margin-bottom: 0.5rem;
        }

        .error-sub-message {
          font-size: 1rem;
          opacity: 0.8;
        }

        .main-card-wrapper {
          background-color: #262a33;
          border-radius: 20px;
          box-shadow: 0 20px 60px rgba(0, 0, 0, 0.6), 0 0 0 1px rgba(255, 255, 255, 0.05);
          display: flex;
          flex-direction: column;
          align-items: center;
          gap: 2rem;
          padding: 3rem;
          max-width: 500px;
          width: 90%;
          animation: fadeInScale 0.8s ease-out forwards;
        }

        .auth0-logo {
          width: 160px;
          margin-bottom: 1.5rem;
          opacity: 0;
          animation: slideInDown 1s ease-out forwards 0.2s;
        }

        .main-title {
          font-size: 2.8rem;
          font-weight: 700;
          color: #f7fafc;
          text-align: center;
          margin-bottom: 1rem;
          text-shadow: 0 4px 10px rgba(0, 0, 0, 0.3);
          opacity: 0;
          animation: fadeIn 1s ease-out forwards 0.4s;
        }

        .action-card {
          background-color: #2d313c;
          border-radius: 15px;
          box-shadow: inset 0 2px 5px rgba(0, 0, 0, 0.3), 0 5px 15px rgba(0, 0, 0, 0.3);
          padding: 2.5rem;
          display: flex;
          flex-direction: column;
          align-items: center;
          gap: 1.8rem;
          width: calc(100% - 2rem);
          opacity: 0;
          animation: fadeIn 1s ease-out forwards 0.6s;
        }

        .action-text {
          font-size: 1.25rem;
          color: #cbd5e0;
          text-align: center;
          line-height: 1.6;
          font-weight: 400;
        }

        .button {
          padding: 1.1rem 2.8rem;
          font-size: 1.2rem;
          font-weight: 600;
          border-radius: 10px;
          border: none;
          cursor: pointer;
          transition: all 0.3s cubic-bezier(0.25, 0.8, 0.25, 1);
          box-shadow: 0 8px 20px rgba(0, 0, 0, 0.4);
          text-transform: uppercase;
          letter-spacing: 0.08em;
          outline: none;
        }

        .button:focus {
          box-shadow: 0 0 0 4px rgba(99, 179, 237, 0.5);
        }

        .button.login {
          background-color: #63b3ed;
          color: #1a1e27;
        }

        .button.login:hover {
          background-color: #4299e1;
          transform: translateY(-5px) scale(1.03);
          box-shadow: 0 12px 25px rgba(0, 0, 0, 0.5);
        }

        .button.logout {
          background-color: #fc8181;
          color: #1a1e27;
        }

        .button.logout:hover {
          background-color: #e53e3e;
          transform: translateY(-5px) scale(1.03);
          box-shadow: 0 12px 25px rgba(0, 0, 0, 0.5);
        }

        .logged-in-section {
          display: flex;
          flex-direction: column;
          align-items: center;
          gap: 1.5rem;
          width: 100%;
        }

        .logged-in-message {
          font-size: 1.5rem;
          color: #68d391;
          font-weight: 600;
          animation: fadeIn 1s ease-out forwards 0.8s;
        }

        .profile-section-title {
          font-size: 2.2rem;
          animation: slideInUp 1s ease-out forwards 1s;
        }

        .profile-card {
          padding: 2.2rem;
          animation: scaleIn 0.8s ease-out forwards 1.2s;
        }

        .profile-picture {
          width: 110px;
          transition: transform 0.3s ease-in-out;
        }

        .profile-picture:hover {
          transform: scale(1.05);
        }

        .profile-name {
          font-size: 2rem;
          margin-top: 0.5rem;
        }

        .profile-email {
          font-size: 1.15rem;
          text-align: center;
        }

        @keyframes fadeIn {
          from { opacity: 0; }
          to { opacity: 1; }
        }

        @keyframes fadeInScale {
          from { opacity: 0; transform: scale(0.95); }
          to { opacity: 1; transform: scale(1); }
        }

        @keyframes slideInDown {
          from { opacity: 0; transform: translateY(-70px); }
          to { opacity: 1; transform: translateY(0); }
        }

        @keyframes slideInUp {
          from { opacity: 0; transform: translateY(50px); }
          to { opacity: 1; transform: translateY(0); }
        }

        @keyframes pulse {
          0%, 100% { opacity: 1; }
          50% { opacity: 0.6; }
        }

        @keyframes scaleIn {
          from { opacity: 0; transform: scale(0.8); }
          to { opacity: 1; transform: scale(1); }
        }

        @media (max-width: 600px) {
          .main-card-wrapper {
            padding: 2rem;
            margin: 1rem;
          }
          
          .main-title {
            font-size: 2.2rem;
          }
          
          .button {
            padding: 1rem 2rem;
            font-size: 1.1rem;
          }
          
          .auth0-logo {
            width: 120px;
          }
        }
        ```
      </Tab>
    </Tabs>
  </Step>

  <Step title="アプリを実行する" stepNumber={6}>
    ```shellscript theme={null}
    ng serve
    ```
  </Step>
</Steps>

<Check>
  **チェックポイント**

  これで、[localhost](http://localhost:4200/) 上で Auth0 のログインページが問題なく動作しているはずです。
</Check>

***

<div id="advanced-usage">
  ## 高度な使い方
</div>

<Accordion title="従来の NgModule アプローチを使用する">
  スタンドアロン コンポーネントではなく NgModule を使用したい場合は、次のようにソフトウェア開発キット (SDK) を設定します。

  ```typescript src/app/app.module.ts theme={null}
  import { NgModule } from '@angular/core';
  import { BrowserModule } from '@angular/platform-browser';
  import { AuthModule } from '@auth0/auth0-angular';
  import { environment } from '../environments/environment';

  import { AppRoutingModule } from './app-routing.module';
  import { AppComponent } from './app';

  @NgModule({
    declarations: [AppComponent],
    imports: [
      BrowserModule,
      AppRoutingModule,
      AuthModule.forRoot({
        domain: environment.auth0.domain,
        clientId: environment.auth0.clientId,
        authorizationParams: {
          redirect_uri: window.location.origin
        }
      })
    ],
    providers: [],
    bootstrap: [AppComponent]
  })
  export class AppModule { }
  ```
</Accordion>

<Accordion title="AuthGuard を使用したルートの保護">
  認証が必要なルートを保護するために、最新の関数型ガードを使用します。

  ```typescript src/app/app.routes.ts theme={null}
  import { Routes } from '@angular/router';
  import { authGuardFn } from '@auth0/auth0-angular';
  import { ProfileComponent } from './components/profile.component';

  export const routes: Routes = [
    {
      path: 'profile',
      component: ProfileComponent,
      canActivate: [authGuardFn]
    },
    {
      path: '',
      redirectTo: '/profile',
      pathMatch: 'full'
    }
  ];
  ```

  次に、main.ts でルーティングを設定します。

  ```typescript src/main.ts theme={null}
  import { provideRouter } from '@angular/router';
  import { environment } from './environments/environment';
  import { routes } from './app/app.routes';

  const auth0Config = mergeApplicationConfig(appConfig, {
    providers: [
      provideRouter(routes),
      provideAuth0({
        domain: environment.auth0.domain,
        clientId: environment.auth0.clientId,
        authorizationParams: {
          redirect_uri: window.location.origin
        }
      })
    ]
  });
  ```
</Accordion>

<Accordion title="保護された API の呼び出し">
  API 呼び出しにトークンを自動的に付与できるよう、HTTP インターセプターを設定します。

  ```typescript src/main.ts theme={null}
  import { provideHttpClient, withInterceptors } from '@angular/common/http';
  import { authHttpInterceptorFn } from '@auth0/auth0-angular';
  import { environment } from './environments/environment';

  const auth0Config = mergeApplicationConfig(appConfig, {
    providers: [
      provideAuth0({
        domain: environment.auth0.domain,
        clientId: environment.auth0.clientId,
        authorizationParams: {
          redirect_uri: window.location.origin,
          audience: 'YOUR_API_IDENTIFIER'
        },
        httpInterceptor: {
          allowedList: [
            'http://localhost:3001/api/*'
          ]
        }
      }),
      provideHttpClient(
        withInterceptors([authHttpInterceptorFn])
      )
    ]
  });
  ```
</Accordion>
