Skip to content

Unable to set UI language on editor #362

@Cheaterman

Description

@Cheaterman

Hello,

As the title says, I'm somehow unable to set UI language on the editor by setting the language key in editor config.

I currently worked around the issue by only setting the translations attribute to the (single) language I want for UI at any given moment, but it feels like a hacky workaround (and probably isn't ideal for caching either).

See the following (spoilered) file. Am I doing something wrong or is this a bug? Or perhaps setting the language in config isn't supported for CDN setups? (if so, it might be a good idea to document the CDN setup limitations)

Code:

<template>
  <div class="main-container">
    <ClientOnly>
      <div
        ref="editorContainerElement"
        class="
          editor-container editor-container_classic-editor
          editor-container_include-block-toolbar
        "
      >
        <div class="editor-container__editor prose max-w-none">
          <div ref="editorElement">
            <Ckeditor
              v-if="editor && config"
              v-model="content"
              :editor="editor"
              :config="config"
            />
          </div>
        </div>
      </div>
    </ClientOnly>
  </div>
</template>

<script setup lang="ts">
import LICENSE_KEY from '@/license_key'
import { Ckeditor, useCKEditorCloud } from '@ckeditor/ckeditor5-vue'
import type {
  ClassicEditor,
  HeadingOption,
  LinkDecoratorDefinition,
  MatcherObjectPattern,
} from 'https://cdn.ckeditor.com/typings/ckeditor5.d.ts'

const content = defineModel<string>()

const { locale } = useI18n()

const cloud = useCKEditorCloud({
  version: '45.2.0',
  // The hacky workaround
  //translations: [locale.value],
  // The original setup
  translations: ['en', 'fr'],
})

const isLayoutReady = ref(false)

const editor = computed(() => {
  if (!cloud.data.value) {
    return null
  }

  return cloud.data.value.CKEditor.ClassicEditor
})

const config = computed(() => {
  if (!isLayoutReady.value) {
    return null
  }

  if (!cloud.data.value) {
    return null
  }

  const {
    Alignment,
    Autoformat,
    AutoImage,
    Autosave,
    BalloonToolbar,
    BlockQuote,
    BlockToolbar,
    Bold,
    Code,
    Essentials,
    FontBackgroundColor,
    FontColor,
    FontFamily,
    FontSize,
    GeneralHtmlSupport,
    Heading,
    HorizontalLine,
    ImageBlock,
    ImageCaption,
    ImageInline,
    ImageInsert,
    ImageInsertViaUrl,
    ImageResize,
    ImageStyle,
    ImageTextAlternative,
    ImageToolbar,
    ImageUpload,
    Indent,
    IndentBlock,
    Italic,
    Link,
    LinkImage,
    List,
    ListProperties,
    MediaEmbed,
    Paragraph,
    PasteFromOffice,
    RemoveFormat,
    ShowBlocks,
    SimpleUploadAdapter,
    SourceEditing,
    Strikethrough,
    Subscript,
    Superscript,
    Table,
    TableCaption,
    TableCellProperties,
    TableColumnResize,
    TableLayout,
    TableProperties,
    TableToolbar,
    TextTransformation,
    Underline
  } = cloud.data.value.CKEditor

  return {
    // The intended way to make this work. Do note I also tried:
    // language: { ui: locale.value }
    // which didn't work either.
    language: locale.value,
    toolbar: {
      items: [
        'undo',
        'redo',
        '|',
        'sourceEditing',
        'showBlocks',
        '|',
        'heading',
        '|',
        'fontSize',
        'fontFamily',
        'fontColor',
        'fontBackgroundColor',
        '|',
        'bold',
        'italic',
        'underline',
        '|',
        'link',
        'insertImage',
        'insertTable',
        'insertTableLayout',
        'blockQuote',
        '|',
        'alignment',
        '|',
        'bulletedList',
        'numberedList',
        'outdent',
        'indent'
      ],
      shouldNotGroupWhenFull: false
    },
    plugins: [
      Alignment,
      Autoformat,
      AutoImage,
      Autosave,
      BalloonToolbar,
      BlockQuote,
      BlockToolbar,
      Bold,
      Code,
      Essentials,
      FontBackgroundColor,
      FontColor,
      FontFamily,
      FontSize,
      GeneralHtmlSupport,
      Heading,
      HorizontalLine,
      ImageBlock,
      ImageCaption,
      ImageInline,
      ImageInsert,
      ImageInsertViaUrl,
      ImageResize,
      ImageStyle,
      ImageTextAlternative,
      ImageToolbar,
      ImageUpload,
      Indent,
      IndentBlock,
      Italic,
      Link,
      LinkImage,
      List,
      ListProperties,
      MediaEmbed,
      Paragraph,
      PasteFromOffice,
      RemoveFormat,
      ShowBlocks,
      SimpleUploadAdapter,
      SourceEditing,
      Strikethrough,
      Subscript,
      Superscript,
      Table,
      TableCaption,
      TableCellProperties,
      TableColumnResize,
      TableLayout,
      TableProperties,
      TableToolbar,
      TextTransformation,
      Underline
    ],
    balloonToolbar: [
      'bold',
      'italic',
      '|',
      'link',
      'insertImage',
      '|',
      'bulletedList',
      'numberedList',
    ],
    blockToolbar: [
      'fontSize',
      'fontColor',
      'fontBackgroundColor',
      '|',
      'bold',
      'italic',
      '|',
      'link',
      'insertImage',
      'insertTable',
      'insertTableLayout',
      '|',
      'bulletedList',
      'numberedList',
      'outdent',
      'indent',
    ],
    fontFamily: {
      supportAllValues: true
    },
    fontSize: {
      options: [10, 12, 14, 'default', 18, 20, 22],
      supportAllValues: true
    },
    heading: {
      options: [
        {
          model: 'paragraph',
          title: 'Paragraph',
          class: 'ck-heading_paragraph'
        },
        {
          model: 'heading2',
          view: 'h2',
          title: 'Heading 2',
          class: 'ck-heading_heading2'
        },
        {
          model: 'heading3',
          view: 'h3',
          title: 'Heading 3',
          class: 'ck-heading_heading3'
        },
      ] as HeadingOption[],
    },
    htmlSupport: {
      allow: [
        {
          name: /^.*$/,
          styles: true,
          attributes: true,
          classes: true
        }
      ] as MatcherObjectPattern[],
    },
    image: {
      toolbar: [
        'toggleImageCaption',
        'imageTextAlternative',
        '|',
        'imageStyle:inline',
        'imageStyle:wrapText',
        'imageStyle:breakText',
        '|',
        'resizeImage',
      ],
    },
    licenseKey: LICENSE_KEY,
    link: {
      addTargetToExternalLinks: true,
      defaultProtocol: 'https://',
      decorators: {
        toggleDownloadable: {
          mode: 'manual',
          label: 'Downloadable',
          attributes: {
            download: 'file'
          }
        } as LinkDecoratorDefinition,
      }
    },
    list: {
      properties: {
        styles: true,
        startIndex: true,
        reversed: true
      }
    },
    menuBar: {
      isVisible: true
    },
    placeholder: 'Type or paste your content here!',
    table: {
      contentToolbar: [
        'tableColumn',
        'tableRow',
        'mergeTableCells',
        'tableProperties',
        'tableCellProperties',
      ]
    },
  }
})

onMounted(() => {
  isLayoutReady.value = true
})
</script>

<style scoped>
@media print {
  body {
    margin: 0 !important;
  }
}

.ck-content {
  line-height: 1.6;
  word-break: break-word;
}
</style>

Thanks in advance!

Metadata

Metadata

Assignees

No one assigned

    Labels

    pending:feedbackThis issue is blocked by necessary feedback.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions