sanity-io / sanity-plugin-internationalized-array

A plugin to register array fields with a custom input component to store field values in multiple languages, queryable by using the language ID as an array `_key`.
MIT License
45 stars 11 forks source link

"Non-unique keys" warning in the studio #80

Open oskarengstrom opened 2 months ago

oskarengstrom commented 2 months ago

Describe the bug

I'm getting a warning in the studio about "Non-unique keys" on a internationalizedArrayString. This is after jsut opening the document fresh

The warning message:

"Non-unique keys Several items in this list share the same identifier (key). Every item must have an unique identifier.

Developer info This usually happens when items are created using an API client, and the _key property of each elements has been generated non-uniquely.

The value of the _key property must be a unique string."

The schema:

{
    name: "title",
    title: "Title",
    type: "internationalizedArrayString",
},

Screenshots

Skärmavbild 2024-10-01 kl  10 54 13 Skärmavbild 2024-10-01 kl  10 54 23

Which versions of Sanity are you using?

"sanity": "^3.58.0",

Which versions of Node.js / npm are you running?

10.2.3 v20.10.0

SimeonGriggs commented 1 month ago

I'm not able to reproduce the error here. Can you share your plugin config as well?

oskarengstrom commented 1 month ago

Sure, is this what you mean:

sanity.config.js:

import { internationalizedArray } from "sanity-plugin-internationalized-array";

export default defineConfig({
  ...
  plugins: [
    ...
    internationalizedArray({
      languages: [
        { id: "sv", title: "Swedish" },
        { id: "en", title: "English" },
      ],
      defaultLanguages: ["sv"],
      fieldTypes: ["string", "text"],
    }),

And then us it like so:

{
  name: "someDoc",
  title: "Some Doc,
  type: "object",
  fields: [
    {
      name: "title",
      title: "Title",
      type: "internationalizedArrayString",
    },
}
oltkachenko commented 1 month ago

Have same issue, for solution here)

internationalizedArray({
    languages: [
        {id: 'en', title: 'English'},
        {id: 'ua', title: 'Ukrainian'},
    ],
    defaultLanguages: ['en'],
    buttonLocations: ['field'],
    fieldTypes: ['string', 'slug'],
})

When I create new document, initial template has array with two object with same "_key" For v2.1.0, which is working for me, this array has only one predefined field from defaultLanguages Screenshot 2024-10-15 144325

NicholasG04 commented 1 month ago

I am getting the exact same issue using this plugin with PortableText blocks.

Config:

fieldTypes: ['string', defineField({ name: 'formattedText', type: 'array', of: [{ type: 'block' }] })],
defaultLanguages: ['en'],
MarchewkaMatthew commented 1 month ago

Same issue for me, here is my config:

    internationalizedArray({
      languages: [
        { id: "en", title: "English" },
        { id: "pl", title: "Polish" },
      ],
      defaultLanguages: ["en"],
      fieldTypes: ["string", "text", "blockContent"],
      buttonAddAll: false,
    }),

(but it's happening for the config from the README as well) For now the only quick-fix for that is to comment out the defaultLanguages field.

My versions:

    "sanity": "^3.61.0",
    "sanity-plugin-internationalized-array": "^3.0.1",
NikLucoz commented 1 month ago

Same issue for me when using v3.0.1. These are my configs:

export default defineConfig({
  basePath: '/studio',
  projectId,
  dataset,
  schema,
  plugins: [
    structureTool({
      structure: myStructure // Use the custom structure
    }),
    visionTool({defaultApiVersion: apiVersion}),
    internationalizedArray({
      languages: [
        {id: 'it', title: 'Italiano'},
        {id: 'en', title: 'Inglese'},
      ],
      defaultLanguages: ['it'],
      fieldTypes: ['string', "text"],
    }),
  ],

  document: {
    // Apply singleton restrictions globally for the defined singleton types
    actions: (input, context) => {
      if (singletonTypes.has(context.schemaType)) {
        return input.filter(({action}) => typeof action === 'string' && singletonActions.has(action))
      }
      return input
    }
  },
})
demandre commented 1 month ago

Hello,

TL;DR : This bug only happens on development mode. Either use next build / next start or disable default language or rollback to previous version if you want to get rid of that.

It is caused by this commit, so only on v3.0.1 : 285d71e

When we are in development mode, React Strict mode renders twice the components for debug purposes. But as we now have a useEffect that does not use _createdAt to know if it needs to add the array entry, it adds it twice because the component is rendered a second time BEFORE the end of the first add row.

In order to fix this, we need to look for alternative for the condition in useEffect to know if we already sent the array push for default language.