Skip to content

Commit f0a599e

Browse files
AlexJerabekMingjiaLiu1995CopilotRick-KirkhamElizabethSamuel-MSFT
authored
[Word, Excel, PowerPoint] Event-based activation walkthrough (#5261)
* Create WXP-event-based-activation.md * Update WXP-event-based-activation.md * Update WXP-event-based-activation.md * Update WXP-event-based-activation.md * Update WXP-event-based-activation.md * Update WXP-event-based-activation.md * Update WXP-event-based-activation.md * Polish article and add to the TOC * Update * Fix typos * Add additional associate call * Use a single commands.js file * Update docs/develop/WXP-event-based-activation.md Co-authored-by: Copilot <[email protected]> * Add an instuction to open Word docs * Apply suggestions from code review Co-authored-by: Rick Kirkham <[email protected]> * Remove associate comment * Update based on Rick-Kirkham's feedback * Update filename to avoid wxp term * Expand npm start step text * Apply suggestions from code review Co-authored-by: Elizabeth Samuel <[email protected]> --------- Co-authored-by: Mingjialiu-MS <[email protected]> Co-authored-by: Copilot <[email protected]> Co-authored-by: Rick Kirkham <[email protected]> Co-authored-by: Elizabeth Samuel <[email protected]>
1 parent 7a94f12 commit f0a599e

File tree

2 files changed

+250
-0
lines changed

2 files changed

+250
-0
lines changed
Lines changed: 248 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,248 @@
1+
---
2+
title: Implement event-based activation in Excel, PowerPoint, and Word add-ins
3+
description: Learn how to develop an Excel, PowerPoint, and Word add-in that implements event-based activation.
4+
ms.date: 06/30/2025
5+
ms.topic: how-to
6+
ms.localizationpriority: medium
7+
---
8+
9+
# Implement event-based activation in Excel, PowerPoint, and Word add-ins
10+
11+
Event-based activation automatically launches a centrally deployed Word, Excel, or PowerPoint add-in whenever a document is created or opened. This allows the add-in to validate, insert, or refresh critical content without any manual operations. The add-in is opened in the background to avoid disrupting the user.
12+
13+
> [!NOTE]
14+
> For information on how to implement event-based activation for Outlook add-ins, see [Configure your Outlook add-in for event-based activation](../outlook/autolaunch.md).
15+
16+
## Supported events and clients
17+
18+
| Event name | Description | Supported clients and channels |
19+
| ----- | ----- | ----- |
20+
| `OnDocumentOpened` | Occurs when a user opens a document or creates a new document, spreadsheet, or presentation. | <ul><li>Windows (build >= 16.0.18324.20032)</li><li>Office on the web</li><li>Office on Mac will be available later </li></ul>|
21+
22+
## Behavior and limitations
23+
24+
As you develop an event-based add-in, be mindful of the following feature behaviors and limitations.
25+
26+
- Office on Mac on is not supported.
27+
- The unified manifest is not supported.
28+
- Event-based add-ins work only when deployed by an administrator. If users install them directly from AppSource or the Office Store, they will not automatically launch. Admin deployments are done by uploading the manifest to the Microsoft 365 admin center.
29+
- If a user installs multiple add-ins that handle the same activation event, only one add-in will be activated. There is no deterministic way to know which add-in will be activated. For example, if multiple add-ins that handle `OnDocumentOpened`, only one of those handlers will run.
30+
- APIs that interact with the UI or display UI elements are not supported for Word, PowerPoint, and Excel on Windows. This is because the event handler runs in a JavaScript-only runtime. For more information, see [Runtimes in Office Add-ins](../testing/runtimes.md).
31+
32+
## Walkthrough: Automatically act when the document opens
33+
34+
The following sections walk you through how to develop a Word add-in that automatically changes the document header when a new or existing document opens. While this specific sample is for Word, the manifest configuration is the same for Excel and PowerPoint.
35+
36+
> [!IMPORTANT]
37+
> This sample requires you to have a Microsoft 365 subscription with the supported version of Word.
38+
39+
### Create a new add-in
40+
41+
Create a new add-in by following the [Word add-in quick start](../quickstarts/word-quickstart-yo.md?tabs=yeoman). This will give you a working Office Add-in to which you can add the event-based activation code.
42+
43+
### Configure the manifest
44+
45+
To enable an event-based add-in, you must configure the following elements in the `VersionOverridesV1_0` node of the manifest.
46+
47+
- In the [Runtimes](/javascript/api/manifest/runtimes) element, make a new [Override element for Runtime](/javascript/api/manifest/override#override-element-for-runtime). Override the "javascript" type and reference the JavaScript file containing the function you want to trigger with the event.
48+
- In the [DesktopFormFactor](/javascript/api/manifest/desktopformfactor) element, add a [FunctionFile](/javascript/api/manifest/functionfile) element for the JavaScript file with the event handler.
49+
- In the [ExtensionPoint](/javascript/api/manifest/extensionpoint) element, set the `xsi:type` to `LaunchEvent`. This enables the event-based activation feature in your add-in.
50+
- In the [LaunchEvent](/javascript/api/manifest/launchevent) element, set the `Type` to `OnDocumentOpened` and specify the JavaScript function name of the event handler in the `FunctionName` attribute.
51+
52+
Use the following sample manifest code to update your project.
53+
54+
1. In your code editor, open the quick start project you created.
55+
1. Open the **manifest.xml** file located at the root of your project.
56+
1. Select the entire **\<VersionOverrides\>** node (including the open and close tags) and replace it with the following XML.
57+
58+
```xml
59+
<VersionOverrides xmlns="http://schemas.microsoft.com/office/taskpaneappversionoverrides" xsi:type="VersionOverridesV1_0">
60+
<Hosts>
61+
<Host xsi:type="Document">
62+
<Runtimes>
63+
<Runtime resid="Taskpane.Url" lifetime="long" />
64+
<Runtime resid="WebViewRuntime.Url">
65+
<Override type="javascript" resid="JsRuntimeWord.Url"/>
66+
</Runtime>
67+
</Runtimes>
68+
<DesktopFormFactor>
69+
<GetStarted>
70+
<Title resid="GetStarted.Title"/>
71+
<Description resid="GetStarted.Description"/>
72+
<LearnMoreUrl resid="GetStarted.LearnMoreUrl"/>
73+
</GetStarted>
74+
<FunctionFile resid="Commands.Url"/>
75+
<ExtensionPoint xsi:type="LaunchEvent">
76+
<LaunchEvents>
77+
<LaunchEvent Type="OnDocumentOpened" FunctionName="changeHeader"></LaunchEvent>
78+
</LaunchEvents>
79+
<SourceLocation resid="WebViewRuntime.Url"/>
80+
</ExtensionPoint>
81+
<ExtensionPoint xsi:type="PrimaryCommandSurface">
82+
<OfficeTab id="TabHome">
83+
<Group id="CommandsGroup">
84+
<Label resid="CommandsGroup.Label"/>
85+
<Icon>
86+
<bt:Image size="16" resid="Icon.16x16"/>
87+
<bt:Image size="32" resid="Icon.32x32"/>
88+
<bt:Image size="80" resid="Icon.80x80"/>
89+
</Icon>
90+
<Control xsi:type="Button" id="TaskpaneButton">
91+
<Label resid="TaskpaneButton.Label"/>
92+
<Supertip>
93+
<Title resid="TaskpaneButton.Label"/>
94+
<Description resid="TaskpaneButton.Tooltip"/>
95+
</Supertip>
96+
<Icon>
97+
<bt:Image size="16" resid="Icon.16x16"/>
98+
<bt:Image size="32" resid="Icon.32x32"/>
99+
<bt:Image size="80" resid="Icon.80x80"/>
100+
</Icon>
101+
<Action xsi:type="ShowTaskpane">
102+
<TaskpaneId>ButtonId1</TaskpaneId>
103+
<SourceLocation resid="Taskpane.Url"/>
104+
</Action>
105+
</Control>
106+
</Group>
107+
</OfficeTab>
108+
</ExtensionPoint>
109+
</DesktopFormFactor>
110+
</Host>
111+
</Hosts>
112+
<Resources>
113+
<bt:Images>
114+
<bt:Image id="Icon.16x16" DefaultValue="https://localhost:3000/assets/icon-16.png"/>
115+
<bt:Image id="Icon.32x32" DefaultValue="https://localhost:3000/assets/icon-32.png"/>
116+
<bt:Image id="Icon.80x80" DefaultValue="https://localhost:3000/assets/icon-80.png"/>
117+
</bt:Images>
118+
<bt:Urls>
119+
<bt:Url id="GetStarted.LearnMoreUrl" DefaultValue="https://go.microsoft.com/fwlink/?LinkId=276812"/>
120+
<bt:Url id="Commands.Url" DefaultValue="https://localhost:3000/commands.html"/>
121+
<bt:Url id="Taskpane.Url" DefaultValue="https://localhost:3000/taskpane.html"/>
122+
<bt:Url id="WebViewRuntime.Url" DefaultValue="https://localhost:3000/commands.html"/>
123+
<bt:Url id="JsRuntimeWord.Url" DefaultValue="https://localhost:3000/commands.js"/>
124+
</bt:Urls>
125+
<bt:ShortStrings>
126+
<bt:String id="GetStarted.Title" DefaultValue="Get started with your sample add-in!"/>
127+
<bt:String id="CommandsGroup.Label" DefaultValue="Event-based add-in activation"/>
128+
<bt:String id="TaskpaneButton.Label" DefaultValue="My add-in"/>
129+
</bt:ShortStrings>
130+
<bt:LongStrings>
131+
<bt:String id="GetStarted.Description" DefaultValue="Your sample add-in loaded successfully. Go to the HOME tab and click the 'Show Task Pane' button to get started."/>
132+
<bt:String id="TaskpaneButton.Tooltip" DefaultValue="Click to show the task pane"/>
133+
</bt:LongStrings>
134+
</Resources>
135+
</VersionOverrides>
136+
```
137+
138+
1. Save your changes.
139+
140+
### Implement the event handler
141+
142+
To enable your add-in to act when the `OnDocumentOpened` event occurs, you must implement a JavaScript event handler. In this section, you'll create the `changeHeader` function, which adds a "Public" header to new documents or a "Highly Confidential" header to existing documents that already have content.
143+
144+
1. In the **./src/commands** folder, open the file named **commands.js**.
145+
1. Replace the entire contents of **commands.js** with the following JavaScript code.
146+
147+
```javascript
148+
/*
149+
* Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
150+
* See LICENSE in the project root for license information.
151+
*/
152+
/* global global, Office, self, window */
153+
154+
Office.onReady(() => {
155+
// If needed, Office.js is ready to be called
156+
});
157+
158+
async function changeHeader(event) {
159+
Word.run(async (context) => {
160+
const body = context.document.body;
161+
body.load("text");
162+
await context.sync();
163+
164+
if (body.text.length == 0) {
165+
// For new or empty documents, make a "Public" header.
166+
const header = context.document.sections.getFirst().getHeader(Word.HeaderFooterType.primary);
167+
const firstPageHeader = context.document.sections.getFirst().getHeader(Word.HeaderFooterType.firstPage);
168+
header.clear();
169+
firstPageHeader.clear();
170+
171+
header.insertParagraph("Public - The data is for the public and shareable externally", "Start");
172+
firstPageHeader.insertParagraph("Public - The data is for the public and shareable externally", "Start");
173+
header.font.color = "#07641d";
174+
firstPageHeader.font.color = "#07641d";
175+
await context.sync();
176+
} else {
177+
// For existing documents, make a "Highly Confidential" header.
178+
const header = context.document.sections.getFirst().getHeader(Word.HeaderFooterType.primary);
179+
const firstPageHeader = context.document.sections.getFirst().getHeader(Word.HeaderFooterType.firstPage);
180+
header.clear();
181+
firstPageHeader.clear();
182+
header.insertParagraph("Highly Confidential - The data must be secret or in some way highly critical", "Start");
183+
firstPageHeader.insertParagraph("Highly Confidential - The data must be secret or in some way highly critical", "Start");
184+
header.font.color = "#f8334d";
185+
firstPageHeader.font.color = "#f8334d";
186+
await context.sync();
187+
}
188+
});
189+
190+
// Calling event.completed is required. event.completed lets the platform know that processing has completed.
191+
event.completed();
192+
}
193+
194+
async function paragraphChanged() {
195+
await Word.run(async (context) => {
196+
const results = context.document.body.search("110");
197+
results.load("length");
198+
await context.sync();
199+
if (results.items.length == 0) {
200+
const header = context.document.sections.getFirst().getHeader(Word.HeaderFooterType.primary);
201+
header.clear();
202+
header.insertParagraph("Public - The data is for the public and shareable externally", "Start");
203+
const font = header.font;
204+
font.color = "#07641d";
205+
206+
await context.sync();
207+
} else {
208+
const header = context.document.sections.getFirst().getHeader(Word.HeaderFooterType.primary);
209+
header.clear();
210+
header.insertParagraph("Highly Confidential - The data must be secret or in some way highly critical", "Start");
211+
const font = header.font;
212+
font.color = "#f8334d";
213+
214+
await context.sync();
215+
}
216+
});
217+
}
218+
219+
async function registerOnParagraphChanged(event) {
220+
Word.run(async (context) => {
221+
let eventContext = context.document.onParagraphChanged.add(paragraphChanged);
222+
await context.sync();
223+
});
224+
// Calling event.completed is required. event.completed lets the platform know that processing has completed.
225+
event.completed();
226+
}
227+
228+
229+
Office.actions.associate("changeHeader", changeHeader);
230+
Office.actions.associate("registerOnParagraphChanged", registerOnParagraphChanged);
231+
```
232+
233+
1. Save your changes.
234+
235+
### Test and validate your add-in
236+
237+
1. Run `npm start` to build your project and launch the web server. **Ignore the Word document that is opened**.
238+
1. Manually sideload your add-in in Word on the web by following the guidance at [Sideload Office Add-ins to Office on the web](../testing/sideload-office-add-ins-for-testing.md#manually-sideload-an-add-in-to-office-on-the-web). Use the **manifest.xml** in the root of the project.
239+
1. Try opening both new and existing Word documents in Word on the web. Headers should automatically be added when they open.
240+
241+
## Deploy your add-in
242+
243+
Event-based add-ins work only when deployed by an administrator. If users install them directly from AppSource or the Office Store, they will not automatically launch. To perform an admin deployment, upload the manifest to the Microsoft 365 admin center by taking the following actions.
244+
245+
1. In the admin portal, expand the **Settings** section in the navigation pane then select **Integrated apps**.
246+
1. On the **Integrated apps** page, choose the **Upload custom apps** action.
247+
248+
For more information about how to deploy an add-in, please refer to [Deploy and publish Office Add-ins in the Microsoft 365 admin center](/microsoft-365/admin/manage/office-addins).

docs/toc.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,8 @@ items:
119119
displayName: manifest
120120
- name: Configure your add-in to use a shared runtime
121121
href: develop/configure-your-add-in-to-use-a-shared-runtime.md
122+
- name: Implement event-based activation
123+
href: develop/event-based-activation.md
122124
- name: Run code on document open
123125
href: develop/run-code-on-document-open.md
124126
- name: Manifest

0 commit comments

Comments
 (0)