6

I'm running a query in Contentful delivery API to return a particular page item based in it's slug. This query is also setting the locale so that it will only return the data in the language I need to render.

However, I also will need to set the hreflang tags of the page to help google know that this page is also available in other languages.

The response I get from contentful for this contentful item that represents my page doesn't seem to have any kind of array property that let's me easily determine what other languages the content is available in.

I'm assuming this must be a pretty common requirement for SEO, so hoping someone can indicate to me how I can get this in the response from Contentful?

Here's an example of my response. What I would have hoped to see was say another property called allLocales that would have a list of every locale that this content could be served with.

Update: I know I can get a list of all locales in the Space, as well as set locales=* in my query, but this still doesn't help. I need to know only the subset of locales that are available on a given piece of content that I have retrieved. For example, one page might only support 2 locales, but there might be 3 or more locales available in the entire space.

Locales=* does not help because it includes locales on every link item (which may or may not have content), and what I need is one single array object that contains all the locales that could be available on the parent content item. Even if a user does not put content in a field, I want to know categorically whether the locale has been selected on the content.

{
    "sys": {
        "type": "Array"
    },
    "total": 1,
    "skip": 0,
    "limit": 1,
    "items": [
        {
            "sys": {
                "space": {
                    "sys": {
                        "type": "Link",
                        "linkType": "Space",
                        "id": "xuehyxrgb9ri"
                    }
                },
                "id": "1MhAzkNYvOSU8GgUQcQKqa",
                "type": "Entry",
                "createdAt": "2018-01-05T10:48:30.373Z",
                "updatedAt": "2018-01-05T12:57:00.066Z",
                "revision": 6,
                "contentType": {
                    "sys": {
                        "type": "Link",
                        "linkType": "ContentType",
                        "id": "contentPage"
                    }
                },
                "locale": "en-AU"
            },
            "fields": {
                "title": "Test Page",
                "slug": "test-page",
                "content": [
                    {
                        "sys": {
                            "type": "Link",
                            "linkType": "Entry",
                            "id": "Vt4ktGvOE0qoO8mqeCMao"
                        }
                    },
                    {
                        "sys": {
                            "type": "Link",
                            "linkType": "Entry",
                            "id": "2jY5LUgHWUsaIyMuwKwYe2"
                        }
                    }
                ]
            }
        }
    ]
}
Chris
  • 7,996
  • 11
  • 66
  • 98
  • 1
    Am I correct in assuming that you want to only display hreflangs for locales where the entry has been fully translated? As in there are no un-translated fields. – Robban Jan 05 '18 at 16:49
  • I was going to make it a bit more rigid than that. As in, if a content editor adds a locale to the content page, then they are explicitly saying that they want that page to have a hreflang tag for each and every locale tog, regardless of whether they've left some untranslated fields. This would mean that, even if they added a locale and didn't translate any of the fields, then it would still get a hreflang tag. It seems simpler to have this managed on the content editor side, than have logic checking every field for a value for a specific lang. – Chris Jan 05 '18 at 18:18
  • Which would make the contentful side easier. It literally just needs a property that lists every single locale that has been added to an entry. Could be every single locale in the space, or could be a subset. What ever the content editor adds to the entry, I need to know it. – Chris Jan 05 '18 at 18:19
  • Unfortunately that's just not how locales work in contentful. An Entry always exist for all locales, it's just individual fields that have a value or not. One workaround would be to add this info as a field for the entry, basically what you suggest. Just make sure not to localise the field and make it a list of values the editor can fill in when a particular locale is ready for publishing. – Robban Jan 05 '18 at 19:21
  • Ah ok. I guess I can do this, just a bit of a bummer as it means the content editor will have to do this twice effectively (once for the locale mechanism in the editor that shows and hides the locales, and once for the custom field I add that has the same locales). Is it possible for me to add a feature request that for any entry returned, a list of all the activated locales is returned in the response meta? – Chris Jan 06 '18 at 11:04
  • Robban, conceptually just want to check something I might have been confused about. Is the "translation" section to the right of the entry in the Contentful simply just a visibility toggle for the UI? If so, then this is clear to me now. – Chris Jan 06 '18 at 11:32
  • Yes, exactly! It is just a simple visibility toggle. A locale is never specifically activated or deactivated by an editor. They're always "there", so to speak. You're not the first one to ask about this though, check out this video to see how optimizely solves a similar problem: https://www.youtube.com/watch?v=mTQhoAiEuus – Robban Jan 06 '18 at 19:31
  • Great thanks Robban, makes total sense now and I'm pretty happy with the solution I'm at. – Chris Jan 08 '18 at 17:05

3 Answers3

1

You can retrieve the locales object that includes an array of all space locales and their configurations (such as default and fallbackCode) by querying the space:

https://www.contentful.com/developers/docs/references/content-delivery-api/#/reference/spaces/space/get-a-space/console/js

  • 1
    Thanks Christine, but I need to know only the subset of locales that are available on a given piece of content that I have retrieved. For example, one page might only support 2 locales, but there might be 3 or more locales available in the entire space. – Chris Jan 05 '18 at 16:43
0

You can achieve that if you request your current space

https://cdn.contentful.com/spaces/<you-space-id>

you will get a response similar to this:

{
  "sys": {
    "type": "Space",
    "id": "developer_bookshelf"
  },
  "name": "Developer Bookshelf",
  "locales": [
    {
      "code": "en-US",
      "default": true,
      "name": "U.S. English",
      "fallbackCode": null
    },
     {
      "code": "de-DE",
      "default": false,
      "name": "German (Germany)",
      "fallbackCode": null
    }

  ]
}

which contains the locales array.

also if you want to get entries with all its locales you just need to change you locale query to locale:*.

Additionally here is how you can achieve that using the js SDK

var contentful = require('contentful')
var client = contentful.createClient({
  // This is the space ID. A space is like a project folder in Contentful terms
  space: '<space-id>',
  // This is the access token for this space. Normally you get both ID and the token in the Contentful web app
  accessToken: '<access-token>'
})
// This API call will request an entry with the specified ID from the space defined at the top, using a space-specific access token.
const space = await client.getSpace()
console.log('space--------------------')
console.log(space)

const localizedEntries = await client.getEntries({locale: '*'})
console.log('localizedEntries--------------------')
console.log(localizedEntries)
Zoe
  • 27,060
  • 21
  • 118
  • 148
Khaled Garbaya
  • 1,479
  • 16
  • 20
  • 1
    Thanks Khaled I updated my answer. This does not help as I can not reliably know which locales are available as they are spead across different properties, and may not display in the response because the user has not put content in it. – Chris Jan 05 '18 at 16:48
0

To programmatically determine the list of languages for which a given page is available, you can make your initial query for /entries?content_type=contentPage&fields.slug=test-page&locale=en-AU to get the entire content for the page (including referenced entries), then take the top entry's ID and make another API request for /entries/<ENTRY_ID>?locale=* and get the keys of the response's fields.<LOCALIZED_FIELD>.

If instead the list of languages for which a given page is available is an editorial decision, I would suggest adding a new field, a short text list, set a predefined values validation with the complete list of possible languages, and use the checkbox appearance. Then an author/editor can select for which languages a page is available and you can simply access that field for the array of languages.

CharlieC
  • 502
  • 3
  • 8
  • It would, but only if at least one of the fields has content for a given locale. I need something more concrete than that, and ideally easier to program against. It should be very simple for contentful to return an array of locales I would think for a given entry. – Chris Jan 05 '18 at 18:20
  • How are you deciding that the page is available in other languages? If that is an editorial decision, I would suggest adding a short text list, set a predefined values validation, and use the checkbox appearance. Then an author/editor can select for which languages/locales a page is available. If it is a programmatic decision, please fully describe your logic you'd like to use and the community can better help. – CharlieC Jan 05 '18 at 20:38
  • It's an editorial decision. Adding a checkbox list would be redundant, as the ability to add locales (and thus show the locale specific fields) to an entry already exists in the content editor in Contentful, and I'd like to avoid the user having to do this twice. – Chris Jan 06 '18 at 11:02
  • What you refer to already existing in the content editor is just defining what locales are visible to the current user in the webapp. It has nothing to do with what locales exist for the current entry. Locales are defined on a space level so every entry has the possibility of having values in every locale. If you want the authors/editors to define which locales an entry is using you would have to add a set of checkboxes like I described. – CharlieC Jun 01 '18 at 21:10