diff --git a/apps/builder/next.config.mjs b/apps/builder/next.config.mjs
index 094f7a8f6..f842162b3 100644
--- a/apps/builder/next.config.mjs
+++ b/apps/builder/next.config.mjs
@@ -22,7 +22,7 @@ const nextConfig = {
],
i18n: {
defaultLocale: 'en',
- locales: ['en', 'fr', 'pt', 'de'],
+ locales: ['en', 'fr', 'pt', 'pt_BR', 'de'],
},
experimental: {
outputFileTracingRoot: join(__dirname, '../../'),
diff --git a/apps/builder/src/features/account/components/UserPreferencesForm.tsx b/apps/builder/src/features/account/components/UserPreferencesForm.tsx
index b95e99f9a..12d3e833a 100644
--- a/apps/builder/src/features/account/components/UserPreferencesForm.tsx
+++ b/apps/builder/src/features/account/components/UserPreferencesForm.tsx
@@ -19,10 +19,11 @@ import { ChevronDownIcon } from '@/components/icons'
import { MoreInfoTooltip } from '@/components/MoreInfoTooltip'
const localeHumanReadable = {
- en: 'English',
- fr: 'Français',
- de: 'Deutsch',
- pt: 'Português',
+ en: 'English',
+ fr: 'Français',
+ de: 'Deutsch',
+ pt: 'Português',
+ pt_BR: 'Português (BR)'
} as const
export const UserPreferencesForm = () => {
diff --git a/apps/builder/src/features/billing/components/CurrentSubscriptionSummary.tsx b/apps/builder/src/features/billing/components/CurrentSubscriptionSummary.tsx
index d31bd474b..93c8caad7 100644
--- a/apps/builder/src/features/billing/components/CurrentSubscriptionSummary.tsx
+++ b/apps/builder/src/features/billing/components/CurrentSubscriptionSummary.tsx
@@ -30,7 +30,8 @@ export const CurrentSubscriptionSummary = ({ workspace }: Props) => {
{data?.subscription?.cancelDate && (
- (Will be cancelled on {data.subscription.cancelDate.toDateString()})
+ ({scopedT('cancelDate')}{' '}
+ {data.subscription.cancelDate.toDateString()})
)}
diff --git a/apps/builder/src/features/billing/components/UsageProgressBars.tsx b/apps/builder/src/features/billing/components/UsageProgressBars.tsx
index 06ba08367..30b5c9fdc 100644
--- a/apps/builder/src/features/billing/components/UsageProgressBars.tsx
+++ b/apps/builder/src/features/billing/components/UsageProgressBars.tsx
@@ -88,7 +88,7 @@ export const UsageProgressBars = ({ workspace }: Props) => {
/{' '}
{workspaceChatsLimit === -1
- ? 'Unlimited'
+ ? scopedT('unlimited')
: parseNumberWithCommas(workspaceChatsLimit)}
@@ -141,7 +141,7 @@ export const UsageProgressBars = ({ workspace }: Props) => {
/{' '}
{workspaceStorageLimit === -1
- ? 'Unlimited'
+ ? scopedT('unlimited')
: `${workspaceStorageLimit} GB`}
diff --git a/apps/builder/src/features/blocks/bubbles/audio/components/AudioBubbleForm.tsx b/apps/builder/src/features/blocks/bubbles/audio/components/AudioBubbleForm.tsx
index cc8471862..403251134 100644
--- a/apps/builder/src/features/blocks/bubbles/audio/components/AudioBubbleForm.tsx
+++ b/apps/builder/src/features/blocks/bubbles/audio/components/AudioBubbleForm.tsx
@@ -4,6 +4,7 @@ import { TextInput } from '@/components/inputs'
import { useState } from 'react'
import { UploadButton } from '@/components/ImageUploadContent/UploadButton'
import { SwitchWithLabel } from '@/components/inputs/SwitchWithLabel'
+import { useScopedI18n } from '@/locales'
type Props = {
fileUploadPath: string
@@ -16,6 +17,7 @@ export const AudioBubbleForm = ({
content,
onContentChange,
}: Props) => {
+ const scopedT = useScopedI18n('editor.blocks.bubbles.audio.settings')
const [currentTab, setCurrentTab] = useState<'link' | 'upload'>('link')
const updateUrl = (url: string) => onContentChange({ ...content, url })
@@ -31,14 +33,14 @@ export const AudioBubbleForm = ({
onClick={() => setCurrentTab('upload')}
size="sm"
>
- Upload
+ {scopedT('upload.label')}
@@ -51,25 +53,25 @@ export const AudioBubbleForm = ({
onFileUploaded={updateUrl}
colorScheme="blue"
>
- Choose a file
+ {scopedT('chooseFile.label')}
)}
{currentTab === 'link' && (
<>
- Works with .MP3s and .WAVs
+ {scopedT('worksWith.text')}
>
)}
diff --git a/apps/builder/src/features/blocks/bubbles/audio/components/AudioBubbleNode.tsx b/apps/builder/src/features/blocks/bubbles/audio/components/AudioBubbleNode.tsx
index 9ad1f75a9..a9eff45e5 100644
--- a/apps/builder/src/features/blocks/bubbles/audio/components/AudioBubbleNode.tsx
+++ b/apps/builder/src/features/blocks/bubbles/audio/components/AudioBubbleNode.tsx
@@ -1,14 +1,17 @@
import { Text } from '@chakra-ui/react'
import { AudioBubbleContent } from '@typebot.io/schemas'
import { isDefined } from '@typebot.io/lib'
+import { useScopedI18n } from '@/locales'
type Props = {
url: AudioBubbleContent['url']
}
-export const AudioBubbleNode = ({ url }: Props) =>
- isDefined(url) ? (
+export const AudioBubbleNode = ({ url }: Props) => {
+ const scopedT = useScopedI18n('editor.blocks.bubbles.audio.node')
+ return isDefined(url) ? (
) : (
- Click to edit...
+ {scopedT('clickToEdit.text')}
)
+}
diff --git a/apps/builder/src/features/blocks/bubbles/embed/components/EmbedBubbleContent.tsx b/apps/builder/src/features/blocks/bubbles/embed/components/EmbedBubbleContent.tsx
index 7d7c1b5df..bf9c5634d 100644
--- a/apps/builder/src/features/blocks/bubbles/embed/components/EmbedBubbleContent.tsx
+++ b/apps/builder/src/features/blocks/bubbles/embed/components/EmbedBubbleContent.tsx
@@ -1,7 +1,14 @@
+import { useScopedI18n } from '@/locales'
import { Text } from '@chakra-ui/react'
import { EmbedBubbleBlock } from '@typebot.io/schemas'
-export const EmbedBubbleContent = ({ block }: { block: EmbedBubbleBlock }) => {
- if (!block.content?.url) return Click to edit...
- return Show embed
+type Props = {
+ block: EmbedBubbleBlock
+}
+
+export const EmbedBubbleContent = ({ block }: Props) => {
+ const scopedT = useScopedI18n('editor.blocks.bubbles.embed.node')
+ if (!block.content?.url)
+ return {scopedT('clickToEdit.text')}
+ return {scopedT('show.text')}
}
diff --git a/apps/builder/src/features/blocks/bubbles/embed/components/EmbedUploadContent.tsx b/apps/builder/src/features/blocks/bubbles/embed/components/EmbedUploadContent.tsx
index 9b757759f..f7dfcc0c5 100644
--- a/apps/builder/src/features/blocks/bubbles/embed/components/EmbedUploadContent.tsx
+++ b/apps/builder/src/features/blocks/bubbles/embed/components/EmbedUploadContent.tsx
@@ -2,6 +2,7 @@ import { TextInput, NumberInput } from '@/components/inputs'
import { HStack, Stack, Text } from '@chakra-ui/react'
import { EmbedBubbleContent } from '@typebot.io/schemas'
import { sanitizeUrl } from '@typebot.io/lib'
+import { useScopedI18n } from '@/locales'
type Props = {
content: EmbedBubbleContent
@@ -9,6 +10,7 @@ type Props = {
}
export const EmbedUploadContent = ({ content, onSubmit }: Props) => {
+ const scopedT = useScopedI18n('editor.blocks.bubbles.embed.settings')
const handleUrlChange = (url: string) => {
const iframeUrl = sanitizeUrl(
url.trim().startsWith('