diff --git a/services/web/frontend/extracted-translations.json b/services/web/frontend/extracted-translations.json
index e1d0f4ee1d..bcda693063 100644
--- a/services/web/frontend/extracted-translations.json
+++ b/services/web/frontend/extracted-translations.json
@@ -1498,6 +1498,7 @@
"suggested": "",
"suggested_fix_for_error_in_path": "",
"suggestion_applied": "",
+ "support_for_your_browser_is_ending_soon": "",
"sure_you_want_to_cancel_plan_change": "",
"sure_you_want_to_change_plan": "",
"sure_you_want_to_delete": "",
@@ -1591,6 +1592,7 @@
"to_change_access_permissions": "",
"to_confirm_transfer_enter_email_address": "",
"to_confirm_unlink_all_users_enter_email": "",
+ "to_continue_using_upgrade_or_change_your_browser": "",
"to_fix_this_you_can": "",
"to_fix_this_you_can_ask_the_github_repository_owner": "",
"to_insert_or_move_a_caption_make_sure_tabular_is_directly_within_table": "",
diff --git a/services/web/frontend/js/features/project-list/components/notifications/user-notifications.tsx b/services/web/frontend/js/features/project-list/components/notifications/user-notifications.tsx
index 1d44c495da..b42ad87347 100644
--- a/services/web/frontend/js/features/project-list/components/notifications/user-notifications.tsx
+++ b/services/web/frontend/js/features/project-list/components/notifications/user-notifications.tsx
@@ -12,6 +12,10 @@ import customLocalStorage from '../../../../infrastructure/local-storage'
import { sendMB } from '../../../../infrastructure/event-tracking'
import GeoBanners from './geo-banners'
import AccessibilitySurveyBanner from './accessibility-survey-banner'
+import {
+ DeprecatedBrowser,
+ isDeprecatedBrowser,
+} from '@/shared/components/deprecated-browser'
const [enrollmentNotificationModule] = importOverleafModules(
'managedGroupSubscriptionEnrollmentNotification'
@@ -94,6 +98,8 @@ function UserNotifications() {
{moduleNotifications.map(({ import: { default: Component }, path }) => (
))}
+
+ {isDeprecatedBrowser() && }
)
diff --git a/services/web/frontend/js/shared/components/deprecated-browser.tsx b/services/web/frontend/js/shared/components/deprecated-browser.tsx
new file mode 100644
index 0000000000..8e5d644ca2
--- /dev/null
+++ b/services/web/frontend/js/shared/components/deprecated-browser.tsx
@@ -0,0 +1,31 @@
+import { FC } from 'react'
+import Notification from '@/shared/components/notification'
+import { Trans, useTranslation } from 'react-i18next'
+import Bowser from 'bowser'
+
+export const isDeprecatedBrowser = () => {
+ const parser = Bowser.getParser(window.navigator.userAgent)
+ return parser.satisfies({
+ safari: '~14',
+ })
+}
+
+export const DeprecatedBrowser: FC = () => {
+ const { t } = useTranslation()
+
+ return (
+ ,
+ ]}
+ />
+ }
+ />
+ )
+}
diff --git a/services/web/frontend/stories/deprecated-browser.stories.tsx b/services/web/frontend/stories/deprecated-browser.stories.tsx
new file mode 100644
index 0000000000..bf1b2dcb16
--- /dev/null
+++ b/services/web/frontend/stories/deprecated-browser.stories.tsx
@@ -0,0 +1,13 @@
+import { Meta, StoryObj } from '@storybook/react'
+import { DeprecatedBrowser } from '@/shared/components/deprecated-browser'
+
+const meta: Meta = {
+ title: 'Project List / Deprecated Browser',
+ component: DeprecatedBrowser,
+}
+
+export default meta
+
+type Story = StoryObj
+
+export const Notification: Story = {}
diff --git a/services/web/locales/en.json b/services/web/locales/en.json
index bd0d1fbb94..c015ad3038 100644
--- a/services/web/locales/en.json
+++ b/services/web/locales/en.json
@@ -2080,6 +2080,7 @@
"suggestion": "Suggestion",
"suggestion_applied": "Suggestion applied",
"support": "Support",
+ "support_for_your_browser_is_ending_soon": "Support for your browser is ending soon",
"sure_you_want_to_cancel_plan_change": "Are you sure you want to revert your scheduled plan change? You will remain subscribed to the <0>__planName__0> plan.",
"sure_you_want_to_change_plan": "Are you sure you want to change plan to <0>__planName__0>?",
"sure_you_want_to_delete": "Are you sure you want to permanently delete the following files?",
@@ -2207,6 +2208,7 @@
"to_confirm_email_address_you_must_be_logged_in_with_the_requesting_account": "To confirm an email address, you must be logged in with the Overleaf account that requested the new secondary email.",
"to_confirm_transfer_enter_email_address": "To accept the invitation, enter the email address linked to your account.",
"to_confirm_unlink_all_users_enter_email": "To confirm you want to unlink all users, enter your email address:",
+ "to_continue_using_upgrade_or_change_your_browser": "To continue using __appName__ without problems you need to upgrade or change to a <0>supported browser0>.",
"to_fix_this_you_can": "To fix this, you can:",
"to_fix_this_you_can_ask_the_github_repository_owner": "To fix this, you can ask the GitHub repository owner (<0>__repoOwnerEmail__0>) to renew their __appName__ subscription and reconnect the project.",
"to_insert_or_move_a_caption_make_sure_tabular_is_directly_within_table": "To insert or move a caption, make sure \\begin{tabular} is directly within a table environment",