diff --git a/services/web/app/src/Features/Uploads/UploadsRouter.mjs b/services/web/app/src/Features/Uploads/UploadsRouter.mjs
index 4727f434f1..82e6658caa 100644
--- a/services/web/app/src/Features/Uploads/UploadsRouter.mjs
+++ b/services/web/app/src/Features/Uploads/UploadsRouter.mjs
@@ -26,13 +26,15 @@ export default {
ProjectUploadController.uploadProject
)
- webRouter.post(
- '/project/new/import-docx',
- AuthenticationController.requireLogin(),
- RateLimiterMiddleware.rateLimit(rateLimiters.projectUpload),
- ProjectUploadController.multerMiddleware,
- ProjectUploadController.importDocx
- )
+ if (Settings.enablePandocConversions) {
+ webRouter.post(
+ '/project/new/import-docx',
+ AuthenticationController.requireLogin(),
+ RateLimiterMiddleware.rateLimit(rateLimiters.projectUpload),
+ ProjectUploadController.multerMiddleware,
+ ProjectUploadController.importDocx
+ )
+ }
const fileUploadEndpoint = '/Project/:Project_id/upload'
const fileUploadRateLimit = RateLimiterMiddleware.rateLimit(
diff --git a/services/web/app/src/infrastructure/ExpressLocals.mjs b/services/web/app/src/infrastructure/ExpressLocals.mjs
index 65bb04b485..3638d83eb9 100644
--- a/services/web/app/src/infrastructure/ExpressLocals.mjs
+++ b/services/web/app/src/infrastructure/ExpressLocals.mjs
@@ -417,6 +417,7 @@ export default async function (webRouter, privateApiRouter, publicApiRouter) {
cioWriteKey: Settings.analytics?.cio?.writeKey,
cioSiteId: Settings.analytics?.cio?.siteId,
linkedInInsightsPartnerId: Settings.analytics?.linkedIn?.partnerId,
+ enablePandocConversions: Settings.enablePandocConversions,
}
next()
})
diff --git a/services/web/config/settings.defaults.js b/services/web/config/settings.defaults.js
index 7c4039b1e9..eaf6c35177 100644
--- a/services/web/config/settings.defaults.js
+++ b/services/web/config/settings.defaults.js
@@ -1104,6 +1104,8 @@ module.exports = {
managedUsers: {
enabled: false,
},
+
+ enablePandocConversions: process.env.ENABLE_PANDOC_CONVERSIONS === 'true',
}
module.exports.mergeWith = function (overrides) {
diff --git a/services/web/cypress/support/ct/window.ts b/services/web/cypress/support/ct/window.ts
index ae2a194bc1..f40fd101fc 100644
--- a/services/web/cypress/support/ct/window.ts
+++ b/services/web/cypress/support/ct/window.ts
@@ -9,6 +9,7 @@ export function resetMeta() {
hasLinkedProjectFileFeature: true,
hasLinkedProjectOutputFileFeature: true,
hasLinkUrlFeature: true,
+ enablePandocConversions: true,
})
}
diff --git a/services/web/docker-compose.common.env b/services/web/docker-compose.common.env
index fe57bd39c3..c5cb1d7285 100644
--- a/services/web/docker-compose.common.env
+++ b/services/web/docker-compose.common.env
@@ -50,3 +50,4 @@ DEVICE_HISTORY_SECRET=1b46e6cdf72db02845da06c9517c9cfbbfa0d87357479f4e1df3ce160b
QUEUE_PROCESSING_ENABLED=true
CURRENT_IMAGE_NAME=texlive-full:2025.1
ALLOWED_IMAGE_NAMES=[{"imageName":"texlive-full:2025.1","imageDesc":"2025"},{"imageName":"wl_texlive:2018.1","imageDesc":"2018"}]
+ENABLE_PANDOC_CONVERSIONS=true
diff --git a/services/web/frontend/js/features/project-list/components/new-project-button.tsx b/services/web/frontend/js/features/project-list/components/new-project-button.tsx
index 636649017b..625e0f3181 100644
--- a/services/web/frontend/js/features/project-list/components/new-project-button.tsx
+++ b/services/web/frontend/js/features/project-list/components/new-project-button.tsx
@@ -58,7 +58,9 @@ function NewProjectButton({
const portalTemplates = getMeta('ol-portalTemplates') || []
const { show: enableAddAffiliationWidget } = useAddAffiliation()
const sendProjectListMB = useSendProjectListMB()
- const docxImportEnabled = useFeatureFlag('import-docx')
+ const docxImportEnabled =
+ useFeatureFlag('import-docx') &&
+ getMeta('ol-ExposedSettings').enablePandocConversions
const sendTrackingEvent = useCallback(
({
dropdownMenu,
diff --git a/services/web/frontend/js/features/project-list/components/welcome-message-new/welcome-message-create-new-project-dropdown.tsx b/services/web/frontend/js/features/project-list/components/welcome-message-new/welcome-message-create-new-project-dropdown.tsx
index 6059671f86..393bcbe477 100644
--- a/services/web/frontend/js/features/project-list/components/welcome-message-new/welcome-message-create-new-project-dropdown.tsx
+++ b/services/web/frontend/js/features/project-list/components/welcome-message-new/welcome-message-create-new-project-dropdown.tsx
@@ -60,7 +60,9 @@ function WelcomeMessageCreateNewProjectDropdown({
}: WelcomeMessageCreateNewProjectDropdownProps) {
const { t } = useTranslation()
const portalTemplates = getMeta('ol-portalTemplates') || []
- const docxImportEnabled = useFeatureFlag('import-docx')
+ const docxImportEnabled =
+ useFeatureFlag('import-docx') &&
+ getMeta('ol-ExposedSettings').enablePandocConversions
const { isOverleaf } = getMeta('ol-ExposedSettings')
diff --git a/services/web/test/frontend/features/project-list/components/welcome-message.test.tsx b/services/web/test/frontend/features/project-list/components/welcome-message.test.tsx
index 9d190502b2..f874f3894a 100644
--- a/services/web/test/frontend/features/project-list/components/welcome-message.test.tsx
+++ b/services/web/test/frontend/features/project-list/components/welcome-message.test.tsx
@@ -14,10 +14,15 @@ const WelcomeMessage = () => {
describe('', function () {
beforeEach(function () {
+ window.metaAttributesCache.set('ol-splitTestVariants', {
+ 'import-docx': 'enabled',
+ })
+
Object.assign(getMeta('ol-ExposedSettings'), {
isOverleaf: true,
wikiEnabled: true,
templatesEnabled: true,
+ enablePandocConversions: true,
})
})
@@ -42,9 +47,24 @@ describe('', function () {
screen.getByText('Blank project')
screen.getByText('Example project')
screen.getByText('Upload project')
+ screen.getByText('Import Word document')
screen.getByText('Import from GitHub')
})
+ it('does not show the import from Word document when the feature is disabled', function () {
+ getMeta('ol-ExposedSettings').enablePandocConversions = false
+ render()
+
+ const button = screen.getByRole('button', {
+ name: 'Create a new project',
+ })
+
+ fireEvent.click(button)
+
+ screen.getByText('Blank project')
+ expect(screen.queryByText('Import Word document')).to.not.exist
+ })
+
it('show the correct dropdown menu for affiliated users', function () {
window.metaAttributesCache.set('ol-portalTemplates', [
{
diff --git a/services/web/types/exposed-settings.ts b/services/web/types/exposed-settings.ts
index 4412a1b848..49fbba7c18 100644
--- a/services/web/types/exposed-settings.ts
+++ b/services/web/types/exposed-settings.ts
@@ -51,4 +51,5 @@ export type ExposedSettings = {
wikiEnabled?: boolean
templatesEnabled?: boolean
linkedInInsightsPartnerId?: string
+ enablePandocConversions: boolean
}