Closed dstrunk closed 4 years ago
SEOmatic isn't going to be useful to you if you run Craft in headless mode, because it matches entries for SEO data based on the route.
You can still use Craft CMS "headless" without enabling Headless mode, which is what I'd suggest doing.
Actually, going to re-open this as a FR
Wondering if it's possible to add a slug filter?
Slug seems to be available while in headlessMode
.
Eg:
{
seomatic(slug:"/", asArray: true) {
#...
}
}
That would be great. Just before headlessMode
I was fetching seomatic like this:
query Seomatic($slug: String!) {
seomatic(uri: $slug, asArray: true) {
metaTitleContainer
metaTagContainer
metaLinkContainer
metaJsonLdContainer
}
}
I don't really understand why this would not work anymore. I do get a return object, but it does not contain my entry SEO.
SEOmatic will not work if you have headlessMode
-- and you do not need headlessMode
to be on to use Craft CMS headless.
It removes all concepts of routing and URLs from the CMS, and SEOmatic depends on URLs for the SEO information @Jones-S
To be clear, this is not working:
query Seomatic($slug: String!) {
seomatic(uri: $slug, asArray: true) {
...because a slug
is not the same as a URI, and slugs are not unique site-wide (two sections can have the same slug, for instance)
@ben-rogerson it's not that simple as just using slug
-- many things depend on some concept of URLs.routing, at least currently.
For instance, what should it return for the canonical URL? What about things like HrefLang?
How can it build a sitemap if no entries have URLs? etc, etc.
In most cases, I don't think you should be using headlessMode
when running Craft CMS as a headless CMS.
Hm but URLs for entries were reintroduced. So that would work again (maybe this is only available on v3.4.x-dev
craft branch...)
This should then resolve the question about canonical URLs.
Either we could introduce an ENV variable to define the frontendURL, or my frontend can do the completion of the url on its own: /de/my-entry-slug
=> https://www.frontend.com/de/my-entry-slug
.
Also I see that certain things may get difficult, like the sitemap, but I handle this anyway in my nuxt app. So what I really need is just the entry specific SEO and the page-wide SEO.
I like the headlessMode
, because it hides a few things, and I think especially it allows to set preview targets for sections: where I can point to my frontend app to display previews.
So I really need headlessMode
.
I like headlessMode
too! But my current recommendation is to not have it on, unless URLs for entries are re-introduced.
I'm guessing that it is in the 3.4.x branch, because I don't see anything in the changelog about URLs being re-introduced?
https://github.com/craftcms/cms/blob/develop/CHANGELOG-v3.md
As for the preview targets, you can do that whether headless mode is on or off; have a look here:
So my current recommendation is to leave headlessMode
at default (that is, set to false
) to work with SEOmatic. I don't think you'll run into any limitations, people have been using it this way long before the headlessMode
flag was introduced.
I get what you're going for, and it's something I need too -- so rest assured, I will make this work. There are just a number of assumptions in SEOmatic about it keying off of a URI-based system, and many SEO tags that by their very nature require URLs.
For the reasons mentioned previously, just using slug
alone will not work... slugs are not globally unique.
Ok, alright. I was mistaken with the preview targets then :). But anyway, URLs are back as you can see: https://github.com/craftcms/cms/issues/4520#issuecomment-531040417
So I am looking forward to a headlessMode
-supporting version. 👍
Thanks for the very quick responses and the good work. Appreciate it.
Correct, but it is in 3.4.x-dev
-- I will be testing that branch with SEOmatic as things proceed.
For now, I would suggest just leaving headlessMode
at the default (false
) -- everything should work fine.
Now that 3.4 is in beta and I see that https://github.com/craftcms/cms/blob/3.4/CHANGELOG-v3.4.md#changed #4520 is in the changelog, do you have an estimate on when we could expect seo to work with graphql in headless mode again?
Just want to plan out an approaching project and decide whether we could be counting on this feature or not. Thank you in advance and cheers.
To be clear, SEOmatic currently does support GraphQL right now (just with Headless Mode off), and if I'm understanding the changes that were made to Craft CMS, it should work with Headless Mode On in Craft CMS 3.4 without me making any changes.
Have you given it a whirl @Jones-S ?
No not yet. I thought if 3.4.x-dev was not supporting it with headless mode true
that it would not run with 3.4.beta either. If the thing I did before (mentioned in: https://github.com/nystudio107/craft-seomatic/issues/485#issuecomment-547825595) works again, I am all happy.
As said, haven't had the chance to try ever since (also wasn't expecting that I had to :) )
It should work -- give it a try with the latest SEOmatic and Craft CMS 3.4.0-beta.5 or later.
I'll leave this issue open until we hear back from you on it.
Alright. Thank you for your quick reply. I will try it out, but that won't happen this week anymore... Too busy. I will get back as soon as I tested it. 👍
Any word on this @Jones-S ?
I have not forgotten this, but unfortunately I have been pretty busy with non-development work. I will probably find time for this next week, and I will then get back here. Sorry for the delay.
Going to assume this is good to go unless I head back otherwise
Finally I have time to look into this. Apology for the delay. Unfortunately it does not work like expected. Either I am missing something, which is definitely very probable or it really does not work:
Short wrap up of what I have:
Craft v3.4.8 installed Seomatic v3.2.43 installed.
Craft in Headless mode: true
I should have uris/slugs within headless mode to target specific pages, which I am trying to use with seomatic like:
query Seomatic($slug: String!) {
seomatic(uri: $slug, asArray: true) {
metaTitleContainer
metaTagContainer
metaLinkContainer
metaJsonLdContainer
}
}
and
{
"slug": "my-page-slug"
}
This only returns a thing like;
{
"data": {
"seomatic": {
"metaTitleContainer": "{\"title\":{\"title\":\"🚧 Craft Demo |\"}}",
"metaTagContainer": "{\"generator\":{\"content\":\"SEOmatic\",\"name\":\"generator\"},\"keywords\":[],\"description\":[],\"referrer\":{\"content\":\"no-referrer-when-downgrade\",\"name\":\"referrer\"},\"robots\":{\"content\":\"none\",\"name\":\"robots\"},\"fb:profile_id\":[],\"fb:app_id\":[],\"og:locale\":{\"content\":\"en_US\",\"property\":\"og:locale\"},\"og:locale:alternate\":[{\"content\":\"de_CH\",\"property\":\"og:locale:alternate\"},{\"content\":\"en_US\",\"property\":\"og:locale:alternate\"}],\"og:site_name\":{\"content\":\"Craft Demo\",\"property\":\"og:site_name\"},\"og:type\":{\"content\":\"website\",\"property\":\"og:type\"},\"og:url\":{\"content\":\"http://localhost:3000/actions/graphql/api\",\"property\":\"og:url\"},\"og:title\":[],\"og:description\":[],\"og:image\":[],\"og:image:width\":[],\"og:image:height\":[],\"og:image:alt\":[],\"og:see_also\":[],\"google-site-verification\":[],\"bing-site-verification\":[],\"pinterest-site-verification\":[]}",
"metaLinkContainer": "{\"canonical\":{\"href\":\"http://localhost:3000/meine-deutsche-seite\",\"rel\":\"canonical\"},\"home\":{\"href\":\"http://localhost:3000/\",\"rel\":\"home\"},\"author\":{\"href\":\"http://localhost:3000/humans.txt\",\"rel\":\"author\",\"type\":\"text/plain\"},\"publisher\":[],\"alternate\":[{\"href\":\"http://localhost:3000\",\"hreflang\":\"de-ch\",\"rel\":\"alternate\"},{\"href\":\"http://localhost:3000/meine-deutsche-seite\",\"hreflang\":\"en-us\",\"rel\":\"alternate\"},{\"href\":\"http://localhost:3000/meine-deutsche-seite\",\"hreflang\":\"x-default\",\"rel\":\"alternate\"}]}",
"metaJsonLdContainer": "{\"mainEntityOfPage\":{\"@context\":\"http://schema.org\",\"@type\":\"WebSite\",\"author\":{\"@id\":\"#identity\"},\"copyrightHolder\":{\"@id\":\"#identity\"},\"creator\":{\"@id\":\"#creator\"},\"mainEntityOfPage\":\"http://localhost:3000/actions/graphql/api\",\"url\":\"http://localhost:3000/actions/graphql/api\"},\"identity\":{\"@context\":\"http://schema.org\",\"@id\":\"#identity\",\"@type\":\"Organization\"},\"creator\":{\"@context\":\"http://schema.org\",\"@id\":\"#creator\",\"@type\":\"Organization\"},\"breadcrumbList\":{\"@context\":\"http://schema.org\",\"@type\":\"BreadcrumbList\",\"description\":\"Breadcrumbs list\",\"itemListElement\":[{\"@type\":\"ListItem\",\"item\":\"http://localhost:3000\",\"name\":\"Homepage\",\"position\":1}],\"name\":\"Breadcrumbs\"}}"
}
}
}
I have clearly set some custom SEO values for this page:
But they don't show up in the result.
I then thought that maybe my multisite setup has something to do with it. Normally I can pass a "site": "default"
for other graphql requests. Seomatic only offers siteId
.
I then tried to add that the siteId:
query Seomatic($slug: String!) {
seomatic(uri: $slug, asArray: true, siteId: 1) {
metaTitleContainer
metaTagContainer
metaLinkContainer
metaJsonLdContainer
}
}
but with either siteId
= 1
, 0
, 2
. I would always get the empty results from above.
Anything you see I have to change? Anything I am missing? Thank you in advance.
@Jones-S the screenshot just below "I have clearly set some custom SEO values for this page:" -- what is this from?
Is this from Content SEO settings? Or from an SEO Settings field?
If the latter, what happens if you put settings into Content SEO?
@Jones-S I think what you are missing is that you need to pass in a full URI
You cannot just pass in a slug
So you'd need something like this:
/blog/my-page-slug
Not just the my-page-slug
example you have. Probably you're thinking it's a slug because you have written:
query Seomatic($slug: String!) {
But that parameter is actually a $uri
-> https://nystudio107.com/docs/seomatic/Advanced.html#headless-spa-api
Slugs are not unique across sections, so we cannot have you just passing in a slug. You need to pass in a URI.
It does indeed work if I change it to /my-page-slug
(in this case the page is on root). 👍🏼
Thanks for that!
Unfortunately it does not work with a multilang page, where I have to pass in the language part of the URI:
This is where I add the SEO content. It is set on a page entry within the SEO tab. The Seomatic SEO preview shows things correctly.
If I use this:
(I will change the name to uri
but for now I left it to be slug
)
It does not show the custom seo text I set for this page.
I tried to pass in the URI as follows:
/de/meine-deutsche-seite
de/meine-deutsche-seite
/meine-deutsche-seite
But none of them works...
(Yesterday I only tried the German entry, that's probably why I did not find anything...)
------ EDIT ------
Sorry, wait. It does work, but now I have to pass in the siteId
!
Summary:
URI
!URI
together with the siteId
! 👍🏼
Another question: In my multisite setup I would normally tell graphql which page I want to get content from with the siteHandle
.
I now fear that if I use the siteId
that this id changes if the craft installation is installed somewhere else. (Just being a burnt child with WordPress experience where everything was linked to changing page ids...)
Am I safe to use the Id
that is currently set or would it even be possibility for you to add a distinction of the site via siteHandle
as well?
in Craft, IDs won't change from one site to another but: https://github.com/nystudio107/craft-seomatic/issues/564
In Craft 3.3, if the
headlessMode
is set totrue
, all template routes and URIs are hidden, which makes entry-specific GraphQL SEOmatic queries difficult (if not impossible … I haven't figured out a way, at least). Would it be possible to add the ability to query by slug, or perhaps query by entry ID?