Skip to content
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
10 changes: 8 additions & 2 deletions apps/frontend/nuxt.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,13 @@ export default defineNuxtConfig({
},
},
},
modules: ['@nuxtjs/i18n', '@pinia/nuxt', 'floating-vue/nuxt', '@sentry/nuxt/module'],
modules: [
'@nuxtjs/i18n',
'@pinia/nuxt',
'floating-vue/nuxt',
// Sentry causes rollup-plugin-inject errors in dev, only enable in production
...(isProduction() ? ['@sentry/nuxt/module'] : []),
],
floatingVue: {
themes: {
'ribbit-popout': {
Expand Down Expand Up @@ -314,7 +320,7 @@ export default defineNuxtConfig({
compatibilityDate: '2025-01-01',
telemetry: false,
experimental: {
asyncContext: isProduction(),
asyncContext: false,
},
sourcemap: { client: 'hidden' },
sentry: {
Expand Down
4 changes: 2 additions & 2 deletions apps/frontend/src/utils/analytics.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import dayjs from 'dayjs'
import { computed, ref, watch } from 'vue'
import { useI18n } from 'vue-i18n'

// note: build step can miss unix import for some reason, so
// we have to import it like this

const { unix } = dayjs

export function useCountryNames(style = 'long') {
const { locale } = useI18n()
const { $i18n } = useNuxtApp()
const locale = $i18n.locale
const displayNames = computed(
() => new Intl.DisplayNames([locale.value], { type: 'region', style }),
)
Expand Down
2 changes: 2 additions & 0 deletions apps/frontend/wrangler.jsonc
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
},
"vars": {
"ENVIRONMENT": "production",
"SENTRY_ENVIRONMENT": "production",
"BASE_URL": "https://api.modrinth.com/v2/",
"BROWSER_BASE_URL": "https://api.modrinth.com/v2/",
"PYRO_BASE_URL": "https://archon.modrinth.com/",
Expand All @@ -45,6 +46,7 @@
"routes": ["staging.modrinth.com/*"],
"vars": {
"ENVIRONMENT": "staging",
"SENTRY_ENVIRONMENT": "staging",
"BASE_URL": "https://staging-api.modrinth.com/v2/",
"BROWSER_BASE_URL": "https://staging-api.modrinth.com/v2/",
"PYRO_BASE_URL": "https://staging-archon.modrinth.com/",
Expand Down
5 changes: 2 additions & 3 deletions packages/ui/src/components/base/IntlFormatted.vue
Original file line number Diff line number Diff line change
@@ -1,17 +1,16 @@
<script setup lang="ts">
import IntlMessageFormat, { type FormatXMLElementFn, type PrimitiveType } from 'intl-messageformat'
import { computed, useSlots, type VNode } from 'vue'
import { useI18n } from 'vue-i18n'

import type { MessageDescriptor } from '../../composables/i18n'
import { getSafeI18n, type MessageDescriptor } from '../../composables/i18n'

const props = defineProps<{
messageId: MessageDescriptor
values?: Record<string, PrimitiveType>
}>()

const slots = useSlots()
const { t, locale } = useI18n()
const { t, locale } = getSafeI18n()

const formattedParts = computed(() => {
const key = props.messageId.id
Expand Down
5 changes: 3 additions & 2 deletions packages/ui/src/composables/how-ago.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { computed, type ComputedRef } from 'vue'
import { useI18n } from 'vue-i18n'

import { getSafeI18n } from './i18n'

export type Formatter = (value: Date | number, options?: FormatOptions) => string

Expand All @@ -10,7 +11,7 @@ export interface FormatOptions {
const formatters = new Map<string, ComputedRef<Intl.RelativeTimeFormat>>()

export function useRelativeTime(): Formatter {
const { locale } = useI18n()
const { locale } = getSafeI18n()

const formatterRef = computed(
() =>
Expand Down
24 changes: 22 additions & 2 deletions packages/ui/src/composables/i18n.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,28 @@
import IntlMessageFormat from 'intl-messageformat'
import type { Ref } from 'vue'
import type { CompileError, MessageCompiler, MessageContext } from 'vue-i18n'
import type { CompileError, Composer, MessageCompiler, MessageContext } from 'vue-i18n'
import { useI18n } from 'vue-i18n'

/**
* Get i18n instance, preferring Nuxt's $i18n to avoid vue-i18n's
* getCurrentInstance() issues on edge runtimes with concurrent SSR requests.
*/
export function getSafeI18n(): Pick<Composer, 't' | 'locale'> {
// Try Nuxt's $i18n first (avoids Error 27 on Cloudflare Workers)
if (typeof useNuxtApp !== 'undefined') {
try {
const { $i18n } = useNuxtApp()
if ($i18n) {
return { t: $i18n.t, locale: $i18n.locale }
}
} catch {
// Not in Nuxt context, fall through
}
}
// Fallback to vue-i18n's useI18n
return useI18n()
}

export interface MessageDescriptor {
id: string
defaultMessage?: string
Expand Down Expand Up @@ -174,7 +194,7 @@ export interface VIntlFormatters {
* Uses vue-i18n's useI18n() under the hood.
*/
export function useVIntl(): VIntlFormatters & { locale: Ref<string> } {
const { t, locale } = useI18n()
const { t, locale } = getSafeI18n()

function formatMessage(descriptor: MessageDescriptor, values?: Record<string, unknown>): string {
const key = descriptor.id
Expand Down
Loading