ワンクリックで
power-pages
Power Pages Code Site (SPA) の開発・ビルド・デプロイ。pac pages upload-code-site でサイト作成からデプロイまで完結する。
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
メニュー
Power Pages Code Site (SPA) の開発・ビルド・デプロイ。pac pages upload-code-site でサイト作成からデプロイまで完結する。
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
SOC 職業分類に基づく
Dataverse テーブル設計・構築・デモデータ投入・セキュリティロール作成。ソリューション作成からテーブル・リレーション・ローカライズ・権限設定まで Python スクリプトで一括構築する。
Power Platform 包括開発標準。共通認証(auth_helper.py)・.env パラメータ・ソリューション運用など全スキル共通の開発基盤を提供する。アイコン生成・HTML メールは横断参照用の共有ユーティリティとして保持。
Copilot Studio の「全く新しいアーキテクチャ」(cliagent テンプレート)エージェントを Dataverse Web API だけで完全自動構築する。UI 手動作成不要。Bot 作成・Instructions/モデル/メモリ設定・フラット Python スキル添付・アイコン登録・公開までスクリプトで完結。MCP サーバー(Dataverse / Work IQ 等)のツール追加は Copilot Studio UI での手動作業とする。
Azure 上のリファレンスアーキテクチャを選定し、テナントのセキュリティガバナンスに準拠した構成で構築・デプロイ・検証する。組織ポリシー(公衆ネットワークアクセス禁止・共有キー禁止・MFA 必須等)の下でも動作する構成を、Private Link / Managed Identity / VNet 統合を用いて実装する。
Power Apps Code Apps(コードファースト)の初期化・Dataverse 接続・UI 設計・開発・デプロイ。TypeScript + React + Tailwind CSS で開発する。CSP 構成・メール送信パターンも含む。
Power Platform ソリューションの全体アーキテクチャを設計する。Copilot Studio / Power Automate / Code Apps / Power Pages / AI Builder の使い分け判断、コンポーネント選定、統合パターンを決定する。
| name | power-pages |
| description | Power Pages Code Site (SPA) の開発・ビルド・デプロイ。pac pages upload-code-site でサイト作成からデプロイまで完結する。 |
| category | ui |
| triggers | ["Power Pages","pac pages","upload-code-site","コードサイト","code site","SPA","ポータル","外部サイト","Power Pages デプロイ","site settings","テーブル権限","table permissions","Web ロール","Enhanced Data Model","powerpagecomponent","403 Forbidden","404 Resource not found","9004010C"] |
公式リファレンス: Power Pages でシングルページ アプリケーションを作成して展開する | Microsoft Learn 新スキル参照: microsoft/power-platform-skills - power-pages
| リファレンス | 内容 |
|---|---|
| upstream 優先構成ガイド | microsoft/power-platform-skills 基準での責務分離・実行順序・刷新方針 |
| Dataverse クライアント実装 | powerPagesFetch/powerPagesFetchResponse・WebApiErrorCode・OData ヘルパー・ページネーション・サービスレイヤーパターン・Code Apps との対比 |
| 認証実装 | SSO・サインアウト・ログインボタン・認証ガード・UI フローの実コード一式・サーバー側 IdP/サイト設定・Code Apps との対比 |
| 認証・認可・テーブル権限(詳細) | EDM 2.0 Code Site の認証/認可/テーブル権限・Web API 共有クライアント・SSO+プロフィール編集・Web ロール管理・テーブル Web API 有効化・site-settings 永続化 |
| Enhanced Data Model テーブル権限 | EDM 2.0 のテーブル権限設定・3 レイヤー権限・N:N バグ・ワークアラウンド |
| 運用と落とし穴 | ビルド・デプロイ・サイト再起動・よくあるエラーと解決策 |
| トラブルシューティング | エラーコード早見表・デバッグ用 Site Settings・既知の無害な警告 |
| レガシー参照用チェックリスト | 旧構成の参照用チェックリスト |
| デザインシステム | UI コンポーネント・テーマ・レイアウトの指針 |
| デザインテンプレート集 | 5 種類の配色テンプレート定義。設計時に提案→選択→適用 |
Dataverse 接続と認証の実装方法はこのファイルで概要を説明し、完全なサンプルコードは上記 References にまとめている。
このスキルは microsoft/power-platform-skills/plugins/power-pages の以下 4 スキルを優先参照して構成する。
| 領域 | upstream スキル | このスキル内の着地 |
|---|---|---|
| 認証・認可 | setup-auth | references/authentication.md |
| Web ロール | create-webroles | references/enhanced-data-model-permissions.md |
| Dataverse CRUD | integrate-webapi | references/dataverse-client.md |
| 権限監査 | audit-permissions | reviews/* + scripts/review_pre_deploy.py |
標準実行順序(刷新後)
.powerpages-site 作成)⚠️ デプロイ後の必須ステップ:
pac pages upload-code-siteでテーブル権限 YAML をデプロイしても、 type=18 の content JSON 内adx_entitypermission_webroleが空のまま残り、Web ロール紐付けが効かない。デプロイ直後にpython scripts/setup_permissions.pyを実行して content のadx_entitypermission_webroleを書き込み、review_pre_deploy.pyの チェック 3.7 が ✅ になることを確認する(さもないと管理者を含む全ユーザーが 403)。詳細は教訓 14。
詳細な責務分離と判断基準は upstream 優先構成ガイド を正本として扱う。
| 観点 | ユーザー認証・Webロール認可 | Dataverse Web API 連携 CRUD |
|---|---|---|
| 上流スキル | setup-auth + create-webroles | integrate-webapi |
| 主目的 | ログイン/ログアウト、認証状態判定、ロールベース UI 制御 | /_api 経由の読み書き(powerPagesFetch/powerPagesFetchResponse、OData ヘルパー) |
| 主な成果物 | authService.ts(AUTH_PROVIDERS 配列)・use-auth.ts・ログイン UI・Web ロール YAML(.powerpages-site/web-roles/) | powerPagesApi.ts、テーブル別 service/hooks、CRUD 画面 |
| サーバー側必須設定 | IdP site settings、Web ロール、テーブル権限へのロール紐付け | テーブル権限(type=18 + adx_entitypermission_webrole)、必要時のみ Webapi 設定 |
| 失敗時の代表症状 | ログインループ、/profile 強制遷移、未認証判定ミス | 401(90040107) / 403 / 404(9004010C, 9004010D) |
| 依存関係 | 先に認証導線を整える(ユーザー実体: contact) | 認証済みセッション Cookie 前提で CRUD を実行 |
推奨適用順:
setup-auth で認証導線を整備create-webroles でロールを確定integrate-webapi で CRUD 実装audit-permissions で権限妥当性を最終監査pac pages upload-code-site がサイト作成とデプロイの両方を行う — API でサイトを事前作成する必要はない2022-03-01-preview) で activate_site.py を使ってアクティブ化upload-code-site は既存テーブル権限の Web ロール紐付けを消すため、毎回 scripts/relink_table_permissions.py(または統合の scripts/deploy_site.py)で再付与する(教訓 15)。npm run deploy(build && upload-code-site だけ)で終わらせないupload-code-site が header/footer/page を正しく構成する.powerpages-site/ は upload-code-site が自動管理する — ただし site-settings/ YAML は手動追加して永続化できる(下記参照)adx_website レコードは絶対に削除しない — EDM 2.0 でもランタイムが起動時に参照するcredentials: "same-origin" を使う — "include" ではない(same-site Cookie 認証)powerpagesitelanguageid が必須 — 未設定だと 404 になるcreatedby はアプリケーションユーザーになるため使えない。ログインユーザーの Contact 情報を自動取得し入力不要にする(教訓 19)npm run dev(localhost)で見た目を確認してから本番デプロイする — 本番デプロイ → ブラウザ確認 → 再デプロイのループは 1 サイクルあたり数十秒〜数分かかり非効率。レイアウト・配色・レスポンシブ崩れは localhost で先に潰し、本番デプロイは最終確認のみに留める(教訓 20)。ただし Power Pages 本体のテーマ CSS(Bootstrap 既定の見出し色など)はローカルには存在せず本番でのみ衝突しうるため、色指定は見出し要素に明示的な color を必ず設定し、デプロイ後の最終確認も省略しない(詳細は トラブルシューティング)初回:
npm run build
→ pac pages upload-code-site ← Inactive Sites に作成
→ py portal/scripts/activate_site.py ← PP API でアクティブ化 (api-version=2022-03-01-preview)
→ py portal/scripts/setup_contact_webapi.py
→ py .github/skills/power-pages/scripts/setup_inquiry_reporter.py ← 報告者 Contact Lookup (教訓 19)
→ py .github/skills/power-pages/scripts/relink_table_permissions.py ← ★ロール再付与+再起動
2回目以降(推奨: 統合スクリプトで一括実行):
py .github/skills/power-pages/scripts/deploy_site.py
(ビルド → upload-code-site → ★relink → 検証 → 再起動 を 1 コマンドで実行)
2回目以降(手動の場合):
npm run build → pac pages upload-code-site
→ py .github/skills/power-pages/scripts/relink_table_permissions.py ← ★必須(省くと 403)
⚠️
npm run build && pac pages upload-code-siteだけで終わらせると、既存テーブル権限の Web ロール紐付けが消えて全件 403 になる(教訓 15)。relink_table_permissions.pyを 毎回実行するか、deploy_site.pyで一括実行すること。両スクリプトともハードコードなし・ すべて.env管理(DATAVERSE_URL/ENV_ID/PAGES_WEBSITE_ID/PP_SUBDOMAIN/RELINK_WEBROLE_NAMES/PORTAL_DIR)。
初回の pac pages upload-code-site はサイトを Inactive Sites に作成する。
アクティブ化は Power Platform API (api-version=2022-03-01-preview) で行う。
POST https://api.powerplatform.com/powerpages/environments/{ENV_ID}/websites?api-version=2022-03-01-preview
Body:
{
"name": "<PAGES_SITE_NAME>",
"subdomain": "<PAGES_SUBDOMAIN>",
"templateName": "DefaultPortalTemplate",
"dataverseOrganizationId": "<org_id>",
"selectedBaseLanguage": 1033,
"websiteRecordId": "<powerpagesiteid>" ← pac pages upload-code-site が作った ID
}
Response: 202 Accepted + Operation-Location ヘッダー
→ Operation-Location を 10 秒間隔でポーリング
→ OperationComplete = 成功、OperationFailed = 失敗
| パラメータ | 取得方法 |
|---|---|
ENV_ID | .env |
PAGES_SITE_NAME | .env / powerpages.config.json の siteName |
PAGES_SUBDOMAIN | .env / ユーザー指定 |
dataverseOrganizationId | GET /api/data/v9.2/organizations?$select=organizationid |
websiteRecordId | GET /api/data/v9.2/powerpagesites から name で検索 |
⚠️ API バージョン注意: 2022-03-01-preview を使用すること。2024-10-01 ではアクティベーションが正しく動作しない。
| ツール | バージョン | 用途 |
|---|---|---|
pac (Power Platform CLI) | 1.44+ | サイト作成・アップロード |
node + npm | 18+ | SPA ビルド |
| Python 3 | 3.10+ | デプロイスクリプト(任意) |
pac CLI 注意: サブコマンドは
pac pages(例:pac pages list,pac pages upload-code-site)。pac power-pagesは無効。pac pages helpでコマンド一覧を確認できる。
DATAVERSE_URL=https://{org}.crm.dynamics.com/
ENV_ID= # Power Platform 環境 ID
PAGES_SITE_NAME= # サイト名 (powerpages.config.json の siteName と一致)
PAGES_SUBDOMAIN= # サブドメイン (例: myportal → myportal.powerappsportals.com)
portal/
├── src/
│ ├── App.tsx ← ルート (HashRouter + Routes)
│ ├── main.tsx ← エントリポイント
│ ├── index.css ← Tailwind CSS
│ ├── components/
│ │ ├── site-layout.tsx ← ヘッダー・ナビ・プロフィールドロップダウン
│ │ ├── require-auth.tsx ← 認証ガードコンポーネント
│ │ ├── mode-toggle.tsx ← ダーク/ライト切替
│ │ └── ui/ ← shadcn/ui コンポーネント
│ ├── hooks/
│ │ └── use-auth.ts ← SSO 認証フック
│ ├── shared/
│ │ ├── powerPagesApi.ts ← ★ Web API 共有クライアント (powerPagesFetch/buildODataUrl 等)
│ │ └── services/
│ │ └── <table>Service.ts ← テーブルごとの CRUD サービス
│ ├── types/
│ │ └── <table>.ts ← エンティティ型・ドメイン型・マッパー
│ ├── lib/
│ │ └── utils.ts ← cn() ユーティリティ
│ ├── config.ts ← サイト名・ロゴ等のブランディング設定(.env の VITE_* を集約)
│ └── pages/
│ ├── home.tsx ← ランディングページ
│ └── profile.tsx ← プロフィール編集 (★ powerPagesApi.ts を使用)
├── dist-site/ ← ビルド出力 (compiledPath)
├── .powerpages-site/ ← upload-code-site が管理 + site-settings YAML 手動追加可
│ └── site-settings/ ← Webapi/* 設定を YAML で永続化
├── .env.example ← ★ ブランディング等の VITE_* 変数サンプル(コピーして .env を作成)
├── powerpages.config.json ← CLI 設定ファイル (必須)
├── package.json
├── vite.config.ts
└── scripts/
├── deploy.py ← デプロイスクリプト (Build→Upload→Restart)
├── activate_site.py ← PP API サイトアクティベーション
├── setup_auth.py ← Entra ID SSO 認証設定 (Site Settings + Liquid 注入)
└── setup_contact_webapi.py ← Contact Web API 有効化 (EDM 2.0 対応)
.env / src/config.ts)デプロイごとに変わるブランディング値はコードに直書きせず、ビルド時の環境変数で差し替える。
テンプレートの .env.example を .env にコピーして値を編集する(.env は .gitignore 済み)。
cp .env.example .env # 値を編集してから npm run build
| 変数 | 用途 | 既定値 |
|---|---|---|
VITE_SITE_NAME | サイト/ブランド表示名(ヘッダーロゴ・フッター・ブラウザタブのタイトル) | Power Pages |
VITE_SITE_LOGO_MARK | ヘッダーロゴのマーク(1〜2 文字の頭文字) | P |
VITE_ プレフィックス必須(Vite はこの接頭辞の変数のみクライアントへ公開)。src/config.ts(SITE_NAME / SITE_LOGO_MARK)に集約し、未設定時は既定値へフォールバック。home.tsx / site-layout.tsx は @/config を import して参照、main.tsx が document.title を設定。{
"siteName": "MySite",
"compiledPath": "dist-site",
"defaultLandingPage": "index.html"
}
pac pages upload-code-site は古いバンドルファイルを自動クリーンアップする。
デフォルトパターン: main.*.js, main.*.css, vendor.*.js, index-*.js, index-*.css 等 10 種。
Vite のデフォルト出力(index-{hash}.js)はカバーされるが、カスタムの命名規則を使う場合は明示指定する:
{
"siteName": "MySite",
"compiledPath": "dist-site",
"defaultLandingPage": "index.html",
"bundleFilePatterns": ["app.*.js", "app.*.css", "style.*.css"]
}
// vite.config.ts
export default defineConfig({
base: "./", // 相対パス(必須)
build: {
outDir: "dist-site", // powerpages.config.json と一致
rollupOptions: {
output: { inlineDynamicImports: true }, // 単一バンドル(推奨)
},
},
});
| 制約 | 理由 |
|---|---|
base: "./" | Power Pages のパス構造に対応 |
inlineDynamicImports: true | コード分割するとロード順問題が発生 |
| Hash ルーティング必須 | History API モードは直接 URL アクセスで 404 |
| 静的 SPA のみ | SSR / ISR 非対応 |
{
"scripts": {
"dev": "vite",
"build": "tsc -b && vite build",
"upload": "pac pages upload-code-site --rootPath . --compiledPath ./dist",
"deploy": "py ../.github/skills/power-pages/scripts/deploy_site.py"
}
}
レイアウト・配色・レスポンシブ対応など見た目に関わる変更は、本番デプロイ前に必ず npm run dev で確認する。
cd portal
npm run dev # http://localhost:5173 などで起動
# ブラウザで表示・配色・レスポンシブを確認してから次のコミット/デプロイへ進む
| 確認できること | 確認できないこと(デプロイ後に要再確認) |
|---|---|
| コンポーネント構造・レイアウト崩れ・レスポンシブ | Power Pages 本体のテーマ CSS との衝突(例: Bootstrap 既定の見出し色が明示指定のない <h1> 等に強制適用される) |
| 自前 CSS の配色・グラデーション・アニメーション | 認証リダイレクト・Web ロール・テーブル権限まわりの挙動 |
| コンポーネント間の状態遷移・フォームバリデーション | Power Pages ランタイムが注入する外部スクリプト/スタイルとの相互作用 |
教訓 20:
<h1>等の見出し要素は、親要素にcolor: #fffを設定していても Power Pages 本体のテーマ CSS(h1への既定色指定)に上書きされることがある(継承より明示指定が常に優先されるため)。見出し要素には必ず明示的にcolorを指定し、ローカル確認だけで満足せず本番デプロイ後にも目視確認する。
環境で .js がブロックされている場合:
js を削除cd portal
npm run build
pac pages upload-code-site --rootPath .
py portal/scripts/activate_site.py
スクリプトが以下を自動実行:
カスタムサブドメインを指定する場合:
py portal/scripts/activate_site.py --subdomain my-portal
py portal/scripts/setup_contact_webapi.py
py .github/skills/standard/scripts/_restart.py
アクティブ化後、URL にアクセスできるまで 60〜90秒 かかる。
cd portal
py ../.github/skills/power-pages/scripts/deploy_site.py
# ビルド → upload-code-site → ★ロール再付与 → 検証 → 再起動 を 1 コマンドで実行する。
# upload-code-site が消す Web ロール紐付けを毎回必ず再付与するため、relink 忘れによる
# 全件 403 事故(教訓 15)を構造的に防ぐ。ハードコードなし・すべて .env 管理。
cd portal
npm run build
pac pages upload-code-site --rootPath . --compiledPath ./dist
# ★ upload-code-site は既存 type=18 の content.adx_entitypermission_webrole を消すため、
# デプロイのたびに全テーブル権限の Web ロールを再付与する(教訓 15)。これを省くと 403。
py ../.github/skills/power-pages/scripts/relink_table_permissions.py
# → relink スクリプトが PAGES_WEBSITE_ID(推奨)または PP_SUBDOMAIN 設定時に自動で再起動する
# (未設定の場合は手動再起動)
/profile(contact Self)を使う場合は、初回のみsetup_contact_self.pyで contact 権限とWebapi/contact/enabled|fieldsを作成しておく(教訓 16):py ../.github/skills/power-pages/scripts/setup_contact_self.py
Power Pages の品質を標準的に維持するための 設計前レビュー と デプロイ前レビュー を提供する。
| レビュー | タイミング | ドキュメント | スクリプト |
|---|---|---|---|
| 設計前レビュー | テーブル設計完了後、SPA 実装開始前 | reviews/pre-design-review.md | scripts/review_pre_design.py |
| デプロイ前レビュー | npm run build 後、pac pages upload-code-site 前 | reviews/pre-deploy-review.md | scripts/review_pre_deploy.py |
# 設計前レビュー(ローカル静的チェックのみ、Dataverse 接続不要)
cd portal
python ../.github/skills/power-pages/scripts/review_pre_design.py
# デプロイ前レビュー(ビルド出力 + Dataverse API チェック)
cd portal
python ../.github/skills/power-pages/scripts/review_pre_deploy.py
# CI/CD でリモートチェックをスキップする場合
SKIP_REMOTE=1 python ../.github/skills/power-pages/scripts/review_pre_deploy.py
標準フロー: 設計前レビュー → 実装 →
npm run devでローカル確認(デザイン変更時は必須・教訓 20) → ビルド → デプロイ前レビュー → デプロイ → 本番での目視確認