travis-r6s / gridsome-source-shopify

Shopify source plugin for Gridsome
https://gridsome-shopify-starter.netlify.com
MIT License
16 stars 14 forks source link

Pass Accept-Language header to query #76

Open 7oats opened 3 years ago

7oats commented 3 years ago

Hello everyone.

I want to build a headless e-commerce with Shopify, Gridsome and the source-shopify-plugin. The site should be multilingual. Shopify provides an api-endpoint to add translations to products, collections, ... To receive translated content, the header needs to contain: "Accept-Language: ". According to the shopify docs it is not possible to do a query with a locale request parameter.

Is there any way to get translated content from shopify storefront-api?

Thank you

travis-r6s commented 3 years ago

Hey @vappler490,

Good question - it would be easy enough to add the Accept-Language header to get a single language, but I would need to make a few changes if you would want it to fetch all content for all translations (or a selection of).

I'll aim to work on this later this week, and let you know when I have a preview you can checkout.

7oats commented 3 years ago

Hey @thetre97,

Thanks for the reply and great that you are looking at this. Yeah there is some work to do. I did some research and found a PR for the same issue at the gatsby shopify plugin. If i understand this approach correctly, it will accept a list of languages and do the queries for all of them. Also there will be a new language-node for filtering the data later in graphql. https://github.com/gatsbyjs/gatsby/pull/27413/commits/680ba957655608932222e296d287defe7f4ed669

travis-r6s commented 3 years ago

So I've found it's quite easy to query the data, just need to work on creating a custom resolver to handle fetching the translations in Gridsome.

7oats commented 3 years ago

Hey @thetre97, Are there any news on this issue?

travis-r6s commented 3 years ago

Hey, sorry - turned out it was a bit more difficult to implement than I thought, so put it off a bit then got distracted 😏

Ideally, how would you want to fetch the translated content in Gridsome? I.e. have multiple nodes of the same type, but each with different locale content similar to Prismic (but id's would need to be different to Shopify id) or have a graphql argument on a translatable field to fetch a specific locale, or different content types for different locales, etc.?

travis-r6s commented 3 years ago

I could provide a couple of examples if you'd like...

7oats commented 3 years ago

Hey, no problem. A graphql argument on a translatable field would be great. It also seems according to your response the easiest way to implement this feature. Another idea of mine was that a returns a list of i.e. two collections with two different locale fields and all the other stuff. The fields with translatable content would be translated. Afterwards it is possible to return the desired collection in computed(). This would solve the problem of the Shopify id. But it may break the whole data-structure.

Sure, please send me some examples.

travis-r6s commented 3 years ago

Okay, so here was the couple of ideas I had:

Translatable fields

Most likely used if you have different pages for different locales, e.g. /fr/some-product:

# I.e. id: "abc123", locale: "fr" (from page context)
query Product ($id: ID!, $locale: String!) {
    product (id: $id) {
        id
        title(locale: $locale)
        originalTitle: title # can be aliased if needed
        description(locale: $locale)
        variants {
            title(locale: $locale)
        }
        alternativeLocales {
            id
            locale
            path
        }
    }
}

Which would return:

"product": {
    "id": "abc123",
    "title": "french title",
    "description": "french description",
    "variants": [{ "title": "french variant title" }],
    "alternativeLocales": [
      {
        "id": "abc122",
        "locale": "en",
        "path": "/en/some-product"
      }
    ]
}

Multiple Nodes

Most likely used if you want to fetch every product locale on a single page, and switch between them. Could either use the existing allProducts query, or create a new query specifically for fetching translations:

# I.e. id: "abc123" (from page context)
query ProductTranslations ($id: ID!, $locale: String!) {
    # allProducts (handle: $handle) {
    productTranslations (id: $id) {
        id
        shopifyId
        title
        description
        variants {
            title
        }
    }
}

Which would return:

"productTranslations": [
  {
    "id": "1",
    "shopifyId": "abc122",
    "title": "english title",
    "description": "english description",
    "variants": [{ "title": "english variant title" }]
  },
  {
    "id": "2",
    "shopifyId": "abc123",
    "title": "french title",
    "description": "french description",
    "variants": [{ "title": "french variant title" }]
  },
  {
    "id": "3",
    "shopifyId": "abc124",
    "title": "spanish title",
    "description": "spanish description",
    "variants": [{ "title": "spanish variant title" }]
  }
]

And you can filter between them using computed, as you mentioned above. Optionally, you could filter which locales you wanted to return.

7oats commented 3 years ago

The first option with translatable fields meets my requirements exactly.

travis-r6s commented 3 years ago

Cool! I'll try to put aside some time to implement it soon.

travis-r6s commented 3 years ago

Hey @vappler490 - just released a beta version that should enable the above functionality. Please check it out, and let me know of any issues...

7oats commented 3 years ago

Hey @thetre97. Thanks for your work. I'm getting this error: Error: Resolver for ShopifyArticle.title must have a "type" property.

shopify_source_locales

travis-r6s commented 3 years ago

Ah okay - I take it you have no articles in your Shopify store?

travis-r6s commented 3 years ago

I have just published an update, which should fix this...?

7oats commented 3 years ago

I tested the translatable fields and it is working! Great job, thanks.

I could also test the translations collection if you like?

travis-r6s commented 3 years ago

Please do!

7oats commented 3 years ago

Hey @thetre97 Sorry for the delayed response, i was quite busy the last weeks. Today i tried to use the Translations Collections and found some issues.

  1. The documentation shows a allShopifyProductTranslations query but i can not find it within my graphql-schema.
  2. If i am using the allShopifyProductTranslation(filter: { id: { eq: $id } }) query i get an empty array even though shopifyProduct(id: $id) returns an object. translatableResources(first: 30, resourceType: PRODUCT) from the shopify admin api returns the product where the "translations": [] array contains the desired translation but only one field is translated (body_hmtl) because the other fields stay the same in both translations.

Let me know if you need more information. I can send you an email if you want.

travis-r6s commented 3 years ago

Can I check you have added the correct config in gridsome.config.js? And do you have a repo I can check out...? And feel free to send an email with more details!