Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,14 @@ Each sample includes its own README with setup steps, deployment notes, and a sc
| <img src="samples/spa/react/fluent-ui-sample/screenshot.png" alt="Bank loan application portal screenshot" width="180" /> | [Fluent UI Bank Loan Application](samples/spa/react/fluent-ui-sample/) | React + Fluent UI | Build a form-driven portal using Fluent UI v9 controls, state management, and a dashboard-style data grid. |
| <img src="samples/spa/react/localization-sample/screenshot.png" alt="Contoso Blogs localization sample screenshot" width="180" /> | [Localization Sample](samples/spa/react/localization-sample/) | React + i18next | Add multilingual content, language switching, and localization patterns to a Power Pages code site. |
| <img src="samples/spa/react/authentication-sample/screenshot.png" alt="Authentication sample burger website screenshot" width="180" /> | [Authentication Sample](samples/spa/react/authentication-sample/) | React + Vite | Explore local sign-in, registration, password reset, invitation redemption, external sign-in, terms acceptance, and role-protected content. |
| <img src="samples/spa/react/web-api-create-record/screenshot.png" alt="Web API create record feedback form screenshot" width="180" /> | [Web API: Create a Record](samples/spa/react/web-api-create-record/) | React + Vite | Learn one focused task: create a Dataverse record from a code site with the Web API (POST), including the anti-forgery token and table permission. |
| <img src="samples/spa/vue/vue-admin-template/screenshot.png" alt="Vue admin template screenshot" width="180" /> | [Vue Admin Template](samples/spa/vue/vue-admin-template/) | Vue + Vite | Start from a Vue 3 admin-style template that can be uploaded as a Power Pages code site. |
| _(no preview)_ | [SharePoint Integration](samples/server-logic/sharepoint-integration/) | Server logic (JavaScript) | Call Microsoft Graph and SharePoint Online from server-side logic to upload files and create Dataverse records. |

## Sample categories

- [SPA Samples](samples/spa/) - code-site samples that use popular frontend frameworks and can be uploaded to Power Pages with the Power Platform CLI.
- [Server Logic Samples](samples/server-logic/) - server-side logic samples that run business logic on the Power Pages server, including external service integrations.

## Resources

Expand Down
17 changes: 17 additions & 0 deletions samples/server-logic/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Power Pages Server Logic Samples

Server logic samples show how to run business logic on the Power Pages server -
for example, calling external services, integrating with Microsoft Graph, or
performing privileged operations that should not run in the browser.

Use this index to choose the sample that best matches the scenario you want to
explore.

## Samples

| Sample | Scenario | Highlights |
| --- | --- | --- |
| [SharePoint Integration](sharepoint-integration/) | Upload event tickets to SharePoint and record registrations | Microsoft Graph access token (client credentials), SharePoint file upload, Dataverse record creation, optional email via `Mail.Send`. |

For setup details, prerequisites, and configuration, see the README in each
sample folder.
1 change: 1 addition & 0 deletions samples/spa/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ Use this index to choose the sample that best matches the framework or scenario
| <img src="react/fluent-ui-sample/screenshot.png" alt="Bank loan application portal screenshot" width="220" /> | [Fluent UI Bank Loan Application](react/fluent-ui-sample/) | React + Fluent UI | Loan application form and dashboard | Fluent UI v9 controls, form validation, tab navigation, and a data grid. |
| <img src="react/localization-sample/screenshot.png" alt="Contoso Blogs localization sample screenshot" width="220" /> | [Localization Sample](react/localization-sample/) | React + i18next | Multilingual blog site | Language switching, translated content, persistent locale selection, and i18next patterns. |
| <img src="react/authentication-sample/screenshot.png" alt="Authentication sample burger website screenshot" width="220" /> | [Authentication Sample](react/authentication-sample/) | React + Vite | Authentication flows | Local sign-in, registration, password reset, invitation redemption, external sign-in, terms acceptance, and protected profile content. |
| <img src="react/web-api-create-record/screenshot.png" alt="Web API create record feedback form screenshot" width="220" /> | [Web API: Create a Record](react/web-api-create-record/) | React + Vite | Create a Dataverse record | A single-purpose feedback form: anti-forgery token, Web API POST to `/_api/`, Web API site settings, and a Create table permission. |
| <img src="vue/vue-admin-template/screenshot.png" alt="Vue admin template screenshot" width="220" /> | [Vue Admin Template](vue/vue-admin-template/) | Vue + Vite | Admin template | Vue 3 app structure, Vite build workflow, and Power Pages upload flow. |

## Common workflow
Expand Down
4 changes: 4 additions & 0 deletions samples/spa/react/web-api-create-record/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
node_modules
dist
*.local
.DS_Store
174 changes: 174 additions & 0 deletions samples/spa/react/web-api-create-record/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
# Power Pages - SPA - Web API: Create a Record

This sample demonstrates **one thing**: how to create a record in a Dataverse
table from a Power Pages code site using the [Power Pages Web API](https://learn.microsoft.com/power-pages/configure/web-api-overview)
(an HTTP `POST`).

It is a small "Share your feedback" form. When the visitor submits, the app
fetches an anti-forgery token and `POST`s a new row to a `Feedback` table.

The entire concept lives in one file: [`src/api/webApi.ts`](src/api/webApi.ts).

## Screenshot

![Web API create record feedback form screenshot](screenshot.png)

## What you will learn

- How to fetch the **anti-forgery token** that Power Pages requires for every
unsafe (`POST`/`PATCH`/`DELETE`) Web API request.
- How to **`POST` a new record** to `/_api/<entity-set-name>` with the correct
OData headers.
- How to read the new record's GUID from the `OData-EntityId` response header.
- How to enable the Web API for a table and grant **Create** with a table
permission.

## Prerequisites

- Node.js 18 or later
- npm
- Microsoft Power Platform CLI 1.43.6 or later
- A Power Pages site in your environment

## Local development

```powershell
npm install
npm run dev
```

The app runs at `http://localhost:5173`. There is no Power Pages runtime when
running locally, so `createFeedback()` simulates a successful create. This lets
you explore the form without a deployed site. (See the `import.meta.env.DEV`
branch in [`src/api/webApi.ts`](src/api/webApi.ts).)

## Build

```powershell
npm run build
```

The build output is written to `dist`.

## Set up the Dataverse table

This sample writes to a single table. Create it (Power Pages > your site >
Dataverse, or the maker portal at <https://make.powerapps.com>) with these
columns:

| Display name | Schema name | Type | Notes |
| --- | --- | --- | --- |
| Name | `sample_name` | Single line of text | Primary name column |
| Rating | `sample_rating` | Whole number | Range 1-5 |
| Comments | `sample_comments` | Multiple lines of text | |

> The app uses the entity set name `sample_feedbacks` (the plural logical name).
> If you create the table with a different prefix, update `FEEDBACK_ENTITY_SET`
> in [`src/api/webApi.ts`](src/api/webApi.ts).

## Configure Power Pages

The Web API is off by default. Turn it on for the `Feedback` table and allow
visitors to create rows.

### 1. Enable the Web API for the table

Add these two [site settings](https://learn.microsoft.com/power-pages/configure/web-api-overview#site-settings)
to your site:

| Site setting name | Value |
| --- | --- |
| `Webapi/sample_feedback/enabled` | `true` |
| `Webapi/sample_feedback/fields` | `*` |

### 2. Grant Create with a table permission

Create a [table permission](https://learn.microsoft.com/power-pages/security/table-permissions)
on the `Feedback` table:

- **Access type**: Global
- **Permission to**: **Create** (and Append/AppendTo if you later relate it to
contacts)
- **Web roles**: the role your visitors use. For an anonymous feedback form,
assign it to **Anonymous Users**; for a signed-in form, use
**Authenticated Users**.

If Create is not granted, the Web API returns **HTTP 403** and the form shows a
message explaining how to fix it.

## Upload the code site

1. Authenticate with Power Platform CLI:

```powershell
pac auth create --environment <Environment URL>
```

1. Allow `*.js` files by removing them from **Blocked Attachments** in
**Privacy + Security** settings for your environment in the Power Pages admin
center.

1. Build and upload:

```powershell
npm run build
pac pages upload-code-site --rootPath .
```

1. Reactivate the **Web API Create Record** site from **Inactive sites** in
Power Pages, then preview it.

## How it works

```ts
// 1. Power Pages requires an anti-forgery token for POST/PATCH/DELETE.
const token = await getAntiForgeryToken() // GET /_layout/tokenhtml

// 2. POST the record to the table's entity set.
await fetch('/_api/sample_feedbacks', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'OData-MaxVersion': '4.0',
'OData-Version': '4.0',
__RequestVerificationToken: token,
},
body: JSON.stringify({
sample_name: 'Avery',
sample_rating: 5,
sample_comments: 'Loved it!',
}),
})
```

## Project structure

```text
web-api-create-record/
├── public/
│ └── feedback.svg
├── src/
│ ├── api/
│ │ └── webApi.ts # The Web API create logic (the focus of this sample)
│ ├── components/
│ │ └── FeedbackForm.tsx # Minimal form that calls createFeedback()
│ ├── App.tsx
│ ├── main.tsx
│ ├── index.css
│ └── vite-env.d.ts
├── index.html
├── package.json
├── powerpages.config.json
├── tsconfig.json
└── vite.config.ts
```

## Technologies used

- [React](https://react.dev/)
- [TypeScript](https://www.typescriptlang.org/)
- [Vite](https://vite.dev/guide/)

## License

MIT
13 changes: 13 additions & 0 deletions samples/spa/react/web-api-create-record/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/feedback.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Power Pages - Web API Create Record</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.tsx"></script>
</body>
</html>
Loading
Loading