Skip to content

[Word] (citation mgmt) Add unified manifest support #967

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 16 commits into from
Jul 8, 2025
Merged
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
28 changes: 24 additions & 4 deletions Samples/word-citation-management/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ products:
- office-word
- office
- m365
- office-teams
languages:
- javascript
extensions:
Expand Down Expand Up @@ -37,9 +38,12 @@ The sample uses the [@orcid/bibtexParseJs](https://github.com/ORCID/bibtexParseJ

## Prerequisites

- Office connected to a Microsoft 365 subscription (including Office on the web).
- [Node.js](https://nodejs.org/) version 16 or greater.
- [npm](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm) version 8 or greater.
- To run the web server on localhost, install a recent version of [npm](https://www.npmjs.com/get-npm) and [Node.js](https://nodejs.org) on your computer. To check if you've already installed these tools, from a command prompt, run the following commands.

```console
node -v
npm -v
```

## Solution

Expand All @@ -52,12 +56,22 @@ The sample uses the [@orcid/bibtexParseJs](https://github.com/ORCID/bibtexParseJ
| Version | Date | Comments |
|----------|------|----------|
| 1.0 | 11-28-2023 | Initial release |
| 1.1 | 7-7-2025 | Add support for the unified manifest for Microsoft 365 |

## Decide on a version of the manifest

- Add-in only manifest
- By default, the sample supports the add-in only manifest, which is the **manifest.xml** file in the sample's root directory **Samples/word-citation-management**. For convenience, a copy of the config files specific to this version can be found in the **manifest-configurations/add-in-only** subfolder.
- To run this version, you can skip to the [Run the sample](#run-the-sample) section.
- Unified manifest for Microsoft 365
- To run the unified manifest for Microsoft 365 (**manifest.json**), you need to copy the files from the **manifest-configurations/unified** subfolder to the sample's root directory, replacing the existing config files.
- Optionally, you can delete the **manifest.xml** file from root directory so only files needed for the unified manifest are present. For convenience, a copy of the .xml manifest is available in the **manifest-configurations/add-in-only** subfolder.

## Run the sample

1. Clone or download this repo.

1. Go to the **Samples\word-citation-management** folder via the command line.
1. Go to the **Samples/word-citation-management** folder via the command line.

1. Run `npm install`.

Expand All @@ -74,6 +88,12 @@ The sample uses the [@orcid/bibtexParseJs](https://github.com/ORCID/bibtexParseJ

1. If the add-in task pane isn't already open in Word, go to the Home tab and choose the **Show Task Pane** button in the ribbon to open it.

1. To stop the web server and uninstall the add-in from Word, run the following command.

```console
npm stop
```

## Try it out

1. In the "Bibliography sources" section of the add-in UI, select the **Choose File** button. Navigate to the local location of your .bib file then open the file.
Expand Down
6 changes: 4 additions & 2 deletions Samples/word-citation-management/assets/sample.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,11 @@
"This sample shows how to manage citations in Word with an add-in. The add-in uses the insertEndnote API to list inserted citations at the end of the document."
],
"creationDateTime": "2023-11-28",
"updateDateTime": "2023-11-28",
"updateDateTime": "2025-07-07",
"products": [
"Office"
"Office",
"Teams",
"TeamsToolkit"
],
"metadata": [
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<OfficeApp xmlns="http://schemas.microsoft.com/office/appforoffice/1.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:bt="http://schemas.microsoft.com/office/officeappbasictypes/1.0" xmlns:ov="http://schemas.microsoft.com/office/taskpaneappversionoverrides" xsi:type="TaskPaneApp">
<Id>96bbbbae-0592-4137-a0c0-33deb1b43b32</Id>
<Version>1.0.0.0</Version>
<ProviderName>Contoso</ProviderName>
<DefaultLocale>en-US</DefaultLocale>
<DisplayName DefaultValue="Citation manager - sample"/>
<Description DefaultValue="A template to get started with citation management."/>
<IconUrl DefaultValue="https://localhost:3000/assets/icon-32.png"/>
<HighResolutionIconUrl DefaultValue="https://localhost:3000/assets/icon-64.png"/>
<SupportUrl DefaultValue="https://www.contoso.com/help"/>
<AppDomains>
<AppDomain>https://www.contoso.com</AppDomain>
</AppDomains>
<Hosts>
<Host Name="Document"/>
</Hosts>
<DefaultSettings>
<SourceLocation DefaultValue="https://localhost:3000/taskpane.html"/>
</DefaultSettings>
<Permissions>ReadWriteDocument</Permissions>
<VersionOverrides xmlns="http://schemas.microsoft.com/office/taskpaneappversionoverrides" xsi:type="VersionOverridesV1_0">
<Hosts>
<Host xsi:type="Document">
<DesktopFormFactor>
<GetStarted>
<Title resid="GetStarted.Title"/>
<Description resid="GetStarted.Description"/>
<LearnMoreUrl resid="GetStarted.LearnMoreUrl"/>
</GetStarted>
<ExtensionPoint xsi:type="PrimaryCommandSurface">
<OfficeTab id="TabHome">
<Group id="CommandsGroup">
<Label resid="CommandsGroup.Label"/>
<Icon>
<bt:Image size="16" resid="Icon.16x16"/>
<bt:Image size="32" resid="Icon.32x32"/>
<bt:Image size="80" resid="Icon.80x80"/>
</Icon>
<Control xsi:type="Button" id="TaskpaneButton">
<Label resid="TaskpaneButton.Label"/>
<Supertip>
<Title resid="TaskpaneButton.Label"/>
<Description resid="TaskpaneButton.Tooltip"/>
</Supertip>
<Icon>
<bt:Image size="16" resid="Icon.16x16"/>
<bt:Image size="32" resid="Icon.32x32"/>
<bt:Image size="80" resid="Icon.80x80"/>
</Icon>
<Action xsi:type="ShowTaskpane">
<TaskpaneId>ButtonId1</TaskpaneId>
<SourceLocation resid="Taskpane.Url"/>
</Action>
</Control>
</Group>
</OfficeTab>
</ExtensionPoint>
</DesktopFormFactor>
</Host>
</Hosts>
<Resources>
<bt:Images>
<bt:Image id="Icon.16x16" DefaultValue="https://localhost:3000/assets/icon-16.png"/>
<bt:Image id="Icon.32x32" DefaultValue="https://localhost:3000/assets/icon-32.png"/>
<bt:Image id="Icon.80x80" DefaultValue="https://localhost:3000/assets/icon-80.png"/>
</bt:Images>
<bt:Urls>
<bt:Url id="GetStarted.LearnMoreUrl" DefaultValue="https://go.microsoft.com/fwlink/?LinkId=276812"/>
<bt:Url id="Taskpane.Url" DefaultValue="https://localhost:3000/taskpane.html"/>
</bt:Urls>
<bt:ShortStrings>
<bt:String id="GetStarted.Title" DefaultValue="Get started with your sample add-in!"/>
<bt:String id="CommandsGroup.Label" DefaultValue="Commands Group"/>
<bt:String id="TaskpaneButton.Label" DefaultValue="Show Task Pane"/>
</bt:ShortStrings>
<bt:LongStrings>
<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."/>
<bt:String id="TaskpaneButton.Tooltip" DefaultValue="Click to show a task pane."/>
</bt:LongStrings>
</Resources>
</VersionOverrides>
</OfficeApp>
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
{
"name": "office-addin-taskpane-js",
"version": "0.0.1",
"repository": {
"type": "git",
"url": "https://github.com/OfficeDev/Office-Addin-TaskPane-JS.git"
},
"license": "MIT",
"config": {
"app_to_debug": "word",
"app_type_to_debug": "desktop",
"dev_server_port": 3000
},
"scripts": {
"build": "webpack --mode production",
"build:dev": "webpack --mode development",
"dev-server": "webpack serve --mode development",
"lint": "office-addin-lint check",
"lint:fix": "office-addin-lint fix",
"prettier": "office-addin-lint prettier",
"start": "office-addin-debugging start manifest.xml",
"start:desktop": "office-addin-debugging start manifest.xml desktop",
"start:web": "office-addin-debugging start manifest.xml web",
"stop": "office-addin-debugging stop manifest.xml",
"validate": "office-addin-manifest validate manifest.xml",
"watch": "webpack --mode development --watch"
},
"dependencies": {
"@orcid/bibtex-parse-js": "0.0.25",
"core-js": "^3.37.1",
"regenerator-runtime": "^0.14.1"
},
"devDependencies": {
"@babel/core": "^7.24.7",
"@babel/preset-env": "^7.24.7",
"@babel/preset-typescript": "^7.24.7",
"@types/office-js": "^1.0.396",
"@types/office-runtime": "^1.0.35",
"acorn": "^8.12.0",
"babel-loader": "^9.1.3",
"copy-webpack-plugin": "^12.0.2",
"eslint-plugin-office-addins": "^3.0.2",
"file-loader": "^6.2.0",
"html-loader": "^5.0.0",
"html-webpack-plugin": "^5.6.0",
"office-addin-cli": "^1.6.3",
"office-addin-debugging": "^6.0.4",
"office-addin-dev-certs": "^1.13.3",
"office-addin-lint": "^2.3.3",
"office-addin-manifest": "^2.0.3",
"office-addin-prettier-config": "^1.2.1",
"os-browserify": "^0.3.0",
"process": "^0.11.10",
"source-map-loader": "^5.0.0",
"ts-loader": "^9.5.1",
"typescript": "^5.5.2",
"webpack": "^5.92.1",
"webpack-cli": "^5.1.4",
"webpack-dev-server": "5.0.4"
},
"prettier": "office-addin-prettier-config",
"browserslist": [
"ie 11"
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
/* eslint-disable no-undef */

const devCerts = require("office-addin-dev-certs");
const CopyWebpackPlugin = require("copy-webpack-plugin");
const HtmlWebpackPlugin = require("html-webpack-plugin");

const urlDev = "https://localhost:3000/";
const urlProd = "https://www.contoso.com/"; // CHANGE THIS TO YOUR PRODUCTION DEPLOYMENT LOCATION

async function getHttpsOptions() {
const httpsOptions = await devCerts.getHttpsServerOptions();
return { ca: httpsOptions.ca, key: httpsOptions.key, cert: httpsOptions.cert };
}

module.exports = async (env, options) => {
const dev = options.mode === "development";
const config = {
devtool: "source-map",
entry: {
polyfill: ["core-js/stable", "regenerator-runtime/runtime"],
taskpane: ["./src/taskpane/taskpane.js", "./src/taskpane/taskpane.html"],
},
output: {
clean: true,
},
resolve: {
extensions: [".html", ".js"],
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: "babel-loader",
options: {
presets: ["@babel/preset-env"],
},
},
},
{
test: /\.html$/,
exclude: /node_modules/,
use: "html-loader",
},
{
test: /\.(png|jpg|jpeg|gif|ico)$/,
type: "asset/resource",
generator: {
filename: "assets/[name][ext][query]",
},
},
],
},
plugins: [
new HtmlWebpackPlugin({
filename: "taskpane.html",
template: "./src/taskpane/taskpane.html",
chunks: ["polyfill", "taskpane"],
}),
new CopyWebpackPlugin({
patterns: [
{
from: "assets/*",
to: "assets/[name][ext][query]",
},
{
from: "manifest*.xml",
to: "[name]" + "[ext]",
transform(content) {
if (dev) {
return content;
} else {
return content.toString().replace(new RegExp(urlDev, "g"), urlProd);
}
},
},
],
}),
],
devServer: {
headers: {
"Access-Control-Allow-Origin": "*",
},
server: {
type: "https",
options: env.WEBPACK_BUILD || options.https !== undefined ? options.https : await getHttpsOptions(),
},
port: process.env.npm_package_config_dev_server_port || 3000,
},
};

return config;
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
# yaml-language-server: $schema=https://aka.ms/teams-toolkit/v1.7/yaml.schema.json
# Visit https://aka.ms/teamsfx-v5.0-guide for details on this file
# Visit https://aka.ms/teamsfx-actions for details on actions
version: v1.7

environmentFolderPath: ./env

# Triggered when 'teamsapp provision' is executed
provision:
- uses: arm/deploy # Deploy given ARM templates parallelly.
with:
# AZURE_SUBSCRIPTION_ID is a built-in environment variable,
# if its value is empty, TeamsFx will prompt you to select a subscription.
# Referencing other environment variables with empty values
# will skip the subscription selection prompt.
subscriptionId: ${{AZURE_SUBSCRIPTION_ID}}
# AZURE_RESOURCE_GROUP_NAME is a built-in environment variable,
# if its value is empty, TeamsFx will prompt you to select or create one
# resource group.
# Referencing other environment variables with empty values
# will skip the resource group selection prompt.
resourceGroupName: ${{AZURE_RESOURCE_GROUP_NAME}}
templates:
- path: ./infra/azure.bicep # Relative path to this file
# Relative path to this yaml file.
# Placeholders will be replaced with corresponding environment
# variable before ARM deployment.
parameters: ./infra/azure.parameters.json
# Required when deploying ARM template
deploymentName: Create-resources-for-tab
# Teams Toolkit will download this bicep CLI version from github for you,
# will use bicep CLI in PATH if you remove this config.
bicepCliVersion: v0.9.1

# Get the deployment token from Azure Static Web Apps
- uses: azureStaticWebApps/getDeploymentToken
with:
resourceId: ${{AZURE_STATIC_WEB_APPS_RESOURCE_ID}}
# Save deployment token to the environment file for the deployment action
writeToEnvironmentFile:
deploymentToken: SECRET_TAB_SWA_DEPLOYMENT_TOKEN

# Triggered when 'teamsapp deploy' is executed
deploy:
# Run npm command
- uses: cli/runNpmCommand
name: install dependencies
with:
args: install
- uses: cli/runNpmCommand
name: build app
with:
args: run build --if-present
# Azure Static Web Apps needs index.html
- uses: cli/runNpxCommand
with:
args: shx touch dist/index.html
# Deploy bits to Azure Static Web Apps
- uses: cli/runNpxCommand
name: deploy to Azure Static Web Apps
with:
args: '@azure/static-web-apps-cli deploy ./dist -d
${{SECRET_TAB_SWA_DEPLOYMENT_TOKEN}} --env production'
projectId: 445fce6e-0384-4531-ade7-dd7b25673031
Loading