LiamMartens/sanity-plugin-intl-input

Difficulty in understanding GraphQL support documentation.

dhanishgajjar opened this issue · 4 comments

I followed the instructions and was able to add the global intl-input.json file in the /config folder and then add the i18n: true, on each schema. It works well, I see the translation options.

However I am not able to understand the GraphQL support section. Would it possible to clarify that more?

I was having trouble with this and have worked out a solution, not sure if this is the intended method but it's working for me so I'm posting it here in case anyone else needs it.

In my example I'm using document level translations

// global config for i18n
// /config/intl-input.json
// using idStructure delimiter because otherwise you won't be able to see content on the graphql playground without providing and access token
{
    "idStructure": "delimiter",
    "referenceBehavior": "hard",
    "base": "en"
}

// cms/schemas/article.js

export default {
  title: 'Article',
  name: 'article',
  type: 'document',
  fields: [
    { name: 'title', title: 'Title', type: 'string' },

    // etc...
  ]
}

// schemas/schema.js

// First, we must import the schema creator
import createSchema from 'part:@sanity/base/schema-creator';
import article from './article';
// Then import schema types from any plugins that might expose them
import schemaTypes from 'all:part:@sanity/base/schema-type';

// helper function which adds i18n config to each schema with type === 'document' to dynamically add the configs and fields to all the custom schema types
const addLocalizationToDocumentType = (schemaType) => {
  if (schemaType.type !== 'document') {
    return schemaType
  }

  return {
    ...schemaType,
    i18n: {
      ...schemaType.i18n,
        base: {name : "en",  title: "English" },
        languages: [{name : "fr",  title: "Français" }, {name : "de",  title: "Deutsch" }],
// change the names of the default fields
        fieldNames: {
          lang: 'i18n_lang',
          references: 'i18n_refs'
        }
    },
// add the fields in so we can query with them on graphql
    fields: [
      ...schemaType.fields,
      {
        name: 'i18n_lang',
        type: 'string',
        hidden: true
      },
      {
        name: 'i18n_refs',
        type: 'array',
        hidden: true,
        of: [{
          type: 'i18n_refs_object',
        }]
      }
    ]
  }
}


const addLocalizationToSchemaType = (schemaType) => {
  if(schemaType.type === 'object') {
    return schemaType
  } else {
    return addLocalizationToDocumentType(schemaType)
  }
}

//  have custom schema types outside you we can map over them in the i18n_refs_object
const customSchemaTypes = [
  article,
]

const i18n_refs_object = {
  name: 'i18n_refs_object',
  type: 'object',
  fields: [{
    type: 'string',
    name: 'lang'
  }, 
  {
    type: 'reference',
    name: 'ref',
// map over all the custom values to create a dynamic array of types which should be referenced
    to: customSchemaTypes.map(customSchema => customSchema?.type === 'document' ? { type: customSchema.name} : null).filter(Boolean)
  }]
};

// Then we give our schema to the builder and provide the result to Sanity
export default createSchema({
  // We name our schema
  name: 'default',
  // Then proceed to concatenate our document type
  // to the ones provided by any plugins that are installed
  types: schemaTypes.concat([
    /* Your types here! */
// add the custom types and map them with the config and fields and finally add the refs object in as well
    ...customSchemaTypes, 
    i18n_refs_object,
  ].map(schema => addLocalizationToSchemaType(schema))),
});

// query the article with the lang and alias a fallback just in case there is no translated content

query article($id: ID!, $lang: String = "en") {
      allArticle(where:{_id: {matches:$id} i18n_lang: { eq: $lang }}) {
       _id
        title
        i18n_lang
      }
      fallback: allArticle(where:{_id: {matches:$id} i18n_lang: { eq: "en}}) {
       _id
        title
        i18n_lang
      }
}

@Axeldeblen yup that solution should work fine - it is actually detailed in short in the docs @dhanishgajjar
https://github.com/LiamMartens/sanity-plugin-intl-input/blob/master/docs/graphql-intl-doc.md

Thanks @LiamMartens I did have a read of that but took me a while to figure out where to add the necessary config/ fields. I think the docs might just need more context for newcomers. I'd be happy to make a PR to amend that section if you like.

Thanks for sharing that example @Axeldeblen, it was helpful.