1
votes

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"
                        }
                    }
                ]
            }
        }
    ]
}
3
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
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
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
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
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

3 Answers

0
votes

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

0
votes

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.

0
votes

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)