From 590e8d1bc8a3665afa5dab1ca0fcd407109e197e Mon Sep 17 00:00:00 2001 From: Martin Grossmann Date: Thu, 4 Jan 2024 15:49:02 +0100 Subject: [PATCH 1/7] brand now can return hreflang links --- src/Model/Resolver/Brand/BrandResolverMap.php | 6 ++++++ .../config/graphql-types/BrandDecorator.types.yaml | 5 +++++ .../Hreflang/HreflangDecorator.types.yaml | 9 +++++++++ .../Hreflang/HreflangLinkDecorator.types.yaml | 11 +++++++++++ 4 files changed, 31 insertions(+) create mode 100644 src/Resources/config/graphql-types/Hreflang/HreflangDecorator.types.yaml create mode 100644 src/Resources/config/graphql-types/Hreflang/HreflangLinkDecorator.types.yaml diff --git a/src/Model/Resolver/Brand/BrandResolverMap.php b/src/Model/Resolver/Brand/BrandResolverMap.php index 905cf7ed9f..2b781202db 100644 --- a/src/Model/Resolver/Brand/BrandResolverMap.php +++ b/src/Model/Resolver/Brand/BrandResolverMap.php @@ -7,6 +7,7 @@ use Overblog\GraphQLBundle\Resolver\ResolverMap; use Shopsys\FrameworkBundle\Component\Domain\Domain; use Shopsys\FrameworkBundle\Model\Product\Brand\Brand; +use Shopsys\FrameworkBundle\Model\Seo\HreflangLinksFacade; use Symfony\Component\Routing\Generator\UrlGeneratorInterface; class BrandResolverMap extends ResolverMap @@ -14,10 +15,12 @@ class BrandResolverMap extends ResolverMap /** * @param \Symfony\Component\Routing\Generator\UrlGeneratorInterface $urlGenerator * @param \Shopsys\FrameworkBundle\Component\Domain\Domain $domain + * @param \Shopsys\FrameworkBundle\Model\Seo\HreflangLinksFacade $hreflangLinksFacade */ public function __construct( protected readonly UrlGeneratorInterface $urlGenerator, protected readonly Domain $domain, + protected readonly HreflangLinksFacade $hreflangLinksFacade, ) { } @@ -44,6 +47,9 @@ protected function map(): array 'seoH1' => function (Brand $brand) { return $brand->getSeoH1($this->domain->getId()); }, + 'hreflangLinks' => function (Brand $brand) { + return $this->hreflangLinksFacade->getForBrand($brand, $this->domain->getId()); + }, ], ]; } diff --git a/src/Resources/config/graphql-types/BrandDecorator.types.yaml b/src/Resources/config/graphql-types/BrandDecorator.types.yaml index e496a75d64..7997905f66 100644 --- a/src/Resources/config/graphql-types/BrandDecorator.types.yaml +++ b/src/Resources/config/graphql-types/BrandDecorator.types.yaml @@ -2,6 +2,8 @@ BrandDecorator: type: object decorator: true config: + interfaces: + - 'Hreflang' description: "Represents a brand" fields: uuid: @@ -41,3 +43,6 @@ BrandDecorator: config: orderingModeType: 'ProductOrderingModeEnum' resolve: '@=query("productsByBrandQuery", args, value)' + hreflangLinks: + type: "[HreflangLink!]!" + description: "Alternate links for hreflang meta tags" diff --git a/src/Resources/config/graphql-types/Hreflang/HreflangDecorator.types.yaml b/src/Resources/config/graphql-types/Hreflang/HreflangDecorator.types.yaml new file mode 100644 index 0000000000..084fe414a9 --- /dev/null +++ b/src/Resources/config/graphql-types/Hreflang/HreflangDecorator.types.yaml @@ -0,0 +1,9 @@ +HreflangDecorator: + type: interface + decorator: true + config: + description: "Represents entity able to return alternate links for hreflang meta tags" + fields: + hreflangLinks: + type: "[HreflangLink!]!" + description: "Alternate links for hreflang meta tags" diff --git a/src/Resources/config/graphql-types/Hreflang/HreflangLinkDecorator.types.yaml b/src/Resources/config/graphql-types/Hreflang/HreflangLinkDecorator.types.yaml new file mode 100644 index 0000000000..860d1d6561 --- /dev/null +++ b/src/Resources/config/graphql-types/Hreflang/HreflangLinkDecorator.types.yaml @@ -0,0 +1,11 @@ +HreflangLinkDecorator: + type: object + decorator: true + config: + fields: + hreflang: + type: "String!" + description: "Language code for hreflang meta tag" + href: + type: "String!" + description: "URL for hreflang meta tag" From 02487e8f25a274319e4e0497d4f5ed7e7a945cd8 Mon Sep 17 00:00:00 2001 From: Martin Grossmann Date: Thu, 4 Jan 2024 17:28:04 +0100 Subject: [PATCH 2/7] category now can return hreflang links --- src/Model/Resolver/Category/CategoryResolverMap.php | 11 +++++++++-- .../config/graphql-types/CategoryDecorator.types.yaml | 3 +++ 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/Model/Resolver/Category/CategoryResolverMap.php b/src/Model/Resolver/Category/CategoryResolverMap.php index a9a40def06..72e51e4b51 100644 --- a/src/Model/Resolver/Category/CategoryResolverMap.php +++ b/src/Model/Resolver/Category/CategoryResolverMap.php @@ -7,14 +7,18 @@ use Overblog\GraphQLBundle\Resolver\ResolverMap; use Shopsys\FrameworkBundle\Component\Domain\Domain; use Shopsys\FrameworkBundle\Model\Category\Category; +use Shopsys\FrameworkBundle\Model\Seo\HreflangLinksFacade; class CategoryResolverMap extends ResolverMap { /** * @param \Shopsys\FrameworkBundle\Component\Domain\Domain $domain + * @param \Shopsys\FrameworkBundle\Model\Seo\HreflangLinksFacade $hreflangLinksFacade */ - public function __construct(protected readonly Domain $domain) - { + public function __construct( + protected readonly Domain $domain, + protected readonly HreflangLinksFacade $hreflangLinksFacade, + ) { } /** @@ -33,6 +37,9 @@ protected function map(): array 'seoMetaDescription' => function (Category $category) { return $category->getSeoMetaDescription($this->domain->getId()); }, + 'hreflangLinks' => function (Category $category) { + return $this->hreflangLinksFacade->getForCategory($category, $this->domain->getId()); + }, ], ]; } diff --git a/src/Resources/config/graphql-types/CategoryDecorator.types.yaml b/src/Resources/config/graphql-types/CategoryDecorator.types.yaml index 75b41a023a..afee2fcf1a 100644 --- a/src/Resources/config/graphql-types/CategoryDecorator.types.yaml +++ b/src/Resources/config/graphql-types/CategoryDecorator.types.yaml @@ -44,3 +44,6 @@ CategoryDecorator: categoryHierarchy: type: "[CategoryHierarchyItem!]!" description: "All parent category names with their IDs and UUIDs" + hreflangLinks: + type: "[HreflangLink!]!" + description: "Alternate links for hreflang meta tags" From ec2a65b20a74a8d08c36efc6049dbed57908e4d9 Mon Sep 17 00:00:00 2001 From: Martin Grossmann Date: Thu, 4 Jan 2024 17:28:56 +0100 Subject: [PATCH 3/7] product now can return hreflang links --- .../Products/DataMapper/ProductArrayFieldMapper.php | 9 +++++++++ .../Products/DataMapper/ProductEntityFieldMapper.php | 12 ++++++++++++ .../graphql-types/MainVariantDecorator.types.yaml | 1 + .../config/graphql-types/ProductDecorator.types.yaml | 3 +++ .../graphql-types/RegularProductDecorator.types.yaml | 1 + .../config/graphql-types/VariantDecorator.types.yaml | 1 + 6 files changed, 27 insertions(+) diff --git a/src/Model/Resolver/Products/DataMapper/ProductArrayFieldMapper.php b/src/Model/Resolver/Products/DataMapper/ProductArrayFieldMapper.php index 4844569046..ded1896767 100644 --- a/src/Model/Resolver/Products/DataMapper/ProductArrayFieldMapper.php +++ b/src/Model/Resolver/Products/DataMapper/ProductArrayFieldMapper.php @@ -206,4 +206,13 @@ public function getMainVariant(array $data): array { return $this->productElasticsearchProvider->getVisibleProductArrayById($data['main_variant_id']); } + + /** + * @param array $data + * @return array + */ + public function getHreflangLinks(array $data): array + { + return $data['hreflang_links']; + } } diff --git a/src/Model/Resolver/Products/DataMapper/ProductEntityFieldMapper.php b/src/Model/Resolver/Products/DataMapper/ProductEntityFieldMapper.php index c2885220ed..cbf963de8d 100644 --- a/src/Model/Resolver/Products/DataMapper/ProductEntityFieldMapper.php +++ b/src/Model/Resolver/Products/DataMapper/ProductEntityFieldMapper.php @@ -9,6 +9,7 @@ use Shopsys\FrameworkBundle\Model\Product\Availability\ProductAvailabilityFacade; use Shopsys\FrameworkBundle\Model\Product\Collection\ProductCollectionFacade; use Shopsys\FrameworkBundle\Model\Product\Product; +use Shopsys\FrameworkBundle\Model\Seo\HreflangLinksFacade; use Shopsys\FrontendApiBundle\Model\Parameter\ParameterWithValuesFactory; use Shopsys\FrontendApiBundle\Model\Product\ProductAccessoryFacade; @@ -21,6 +22,7 @@ class ProductEntityFieldMapper * @param \Shopsys\FrameworkBundle\Model\Customer\User\CurrentCustomerUser $currentCustomerUser * @param \Shopsys\FrontendApiBundle\Model\Parameter\ParameterWithValuesFactory $parameterWithValuesFactory * @param \Shopsys\FrameworkBundle\Model\Product\Availability\ProductAvailabilityFacade $productAvailabilityFacade + * @param \Shopsys\FrameworkBundle\Model\Seo\HreflangLinksFacade $hreflangLinksFacade */ public function __construct( protected readonly Domain $domain, @@ -29,6 +31,7 @@ public function __construct( protected readonly CurrentCustomerUser $currentCustomerUser, protected readonly ParameterWithValuesFactory $parameterWithValuesFactory, protected readonly ProductAvailabilityFacade $productAvailabilityFacade, + protected readonly HreflangLinksFacade $hreflangLinksFacade, ) { } @@ -157,4 +160,13 @@ public function getOrderingPriority(Product $product): int { return $product->getOrderingPriority($this->domain->getId()); } + + /** + * @param \Shopsys\FrameworkBundle\Model\Product\Product $product + * @return \Shopsys\FrameworkBundle\Model\Seo\HreflangLink[] + */ + public function getHreflangLinks(Product $product): array + { + return $this->hreflangLinksFacade->getForProduct($product, $this->domain->getId()); + } } diff --git a/src/Resources/config/graphql-types/MainVariantDecorator.types.yaml b/src/Resources/config/graphql-types/MainVariantDecorator.types.yaml index e13a95ef48..04d5ec4b9a 100644 --- a/src/Resources/config/graphql-types/MainVariantDecorator.types.yaml +++ b/src/Resources/config/graphql-types/MainVariantDecorator.types.yaml @@ -9,3 +9,4 @@ MainVariantDecorator: type: '[Variant!]!' interfaces: - 'Product' + - 'Hreflang' diff --git a/src/Resources/config/graphql-types/ProductDecorator.types.yaml b/src/Resources/config/graphql-types/ProductDecorator.types.yaml index f937b8a8b6..7fa9af43e0 100644 --- a/src/Resources/config/graphql-types/ProductDecorator.types.yaml +++ b/src/Resources/config/graphql-types/ProductDecorator.types.yaml @@ -68,3 +68,6 @@ ProductDecorator: seoMetaDescription: type: "String" description: "Seo meta description of product" + hreflangLinks: + type: "[HreflangLink!]!" + description: "Alternate links for hreflang meta tags" diff --git a/src/Resources/config/graphql-types/RegularProductDecorator.types.yaml b/src/Resources/config/graphql-types/RegularProductDecorator.types.yaml index 1c649e5868..e1879e8d6a 100644 --- a/src/Resources/config/graphql-types/RegularProductDecorator.types.yaml +++ b/src/Resources/config/graphql-types/RegularProductDecorator.types.yaml @@ -6,3 +6,4 @@ RegularProductDecorator: config: interfaces: - 'Product' + - 'Hreflang' diff --git a/src/Resources/config/graphql-types/VariantDecorator.types.yaml b/src/Resources/config/graphql-types/VariantDecorator.types.yaml index d50d2835e3..6ee3d77bea 100644 --- a/src/Resources/config/graphql-types/VariantDecorator.types.yaml +++ b/src/Resources/config/graphql-types/VariantDecorator.types.yaml @@ -9,3 +9,4 @@ VariantDecorator: type: 'MainVariant' interfaces: - 'Product' + - 'Hreflang' From 4b143c89f65d8be4cebb2093657c751913f55cca Mon Sep 17 00:00:00 2001 From: Martin Grossmann Date: Fri, 5 Jan 2024 14:21:43 +0100 Subject: [PATCH 4/7] blog article now can return hreflang links --- src/Model/Blog/Article/BlogArticleResolverMap.php | 3 +++ .../config/graphql-types/BlogArticleDecorator.types.yaml | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/src/Model/Blog/Article/BlogArticleResolverMap.php b/src/Model/Blog/Article/BlogArticleResolverMap.php index d62715c601..1dfab7687a 100644 --- a/src/Model/Blog/Article/BlogArticleResolverMap.php +++ b/src/Model/Blog/Article/BlogArticleResolverMap.php @@ -40,6 +40,9 @@ protected function map(): array 'link' => static function (array $blogArticleData) { return $blogArticleData['url']; }, + 'hreflangLinks' => function (array $blogArticleData) { + return $blogArticleData['hreflangLinks']; + }, ], ]; } diff --git a/src/Resources/config/graphql-types/BlogArticleDecorator.types.yaml b/src/Resources/config/graphql-types/BlogArticleDecorator.types.yaml index 368b596dc2..6f1b47f479 100644 --- a/src/Resources/config/graphql-types/BlogArticleDecorator.types.yaml +++ b/src/Resources/config/graphql-types/BlogArticleDecorator.types.yaml @@ -6,6 +6,7 @@ BlogArticleDecorator: - 'Breadcrumb' - 'Slug' - 'ArticleInterface' + - 'Hreflang' fields: id: type: "Int!" @@ -68,3 +69,6 @@ BlogArticleDecorator: type: type: "String" defaultValue: null + hreflangLinks: + type: "[HreflangLink!]!" + description: "Alternate links for hreflang meta tags" From fcea97b54a8610112798557315a74f665ab4ddfc Mon Sep 17 00:00:00 2001 From: Martin Grossmann Date: Mon, 8 Jan 2024 12:08:01 +0100 Subject: [PATCH 5/7] blog category now can return hreflang links --- src/Model/Blog/Category/BlogCategoryResolverMap.php | 6 ++++++ .../config/graphql-types/BlogCategoryDecorator.types.yaml | 4 ++++ 2 files changed, 10 insertions(+) diff --git a/src/Model/Blog/Category/BlogCategoryResolverMap.php b/src/Model/Blog/Category/BlogCategoryResolverMap.php index c4b767d407..f2be7efcd7 100644 --- a/src/Model/Blog/Category/BlogCategoryResolverMap.php +++ b/src/Model/Blog/Category/BlogCategoryResolverMap.php @@ -10,6 +10,7 @@ use Shopsys\FrameworkBundle\Model\Blog\Article\Elasticsearch\BlogArticleElasticsearchFacade; use Shopsys\FrameworkBundle\Model\Blog\Category\BlogCategory; use Shopsys\FrameworkBundle\Model\Blog\Category\BlogCategoryFacade; +use Shopsys\FrameworkBundle\Model\Seo\HreflangLinksFacade; class BlogCategoryResolverMap extends ResolverMap { @@ -18,12 +19,14 @@ class BlogCategoryResolverMap extends ResolverMap * @param \Shopsys\FrameworkBundle\Component\Router\FriendlyUrl\FriendlyUrlFacade $friendlyUrlFacade * @param \Shopsys\FrameworkBundle\Model\Blog\Category\BlogCategoryFacade $blogCategoryFacade * @param \Shopsys\FrameworkBundle\Model\Blog\Article\Elasticsearch\BlogArticleElasticsearchFacade $blogArticleElasticsearchFacade + * @param \Shopsys\FrameworkBundle\Model\Seo\HreflangLinksFacade $hreflangLinksFacade */ public function __construct( protected readonly Domain $domain, protected readonly FriendlyUrlFacade $friendlyUrlFacade, protected readonly BlogCategoryFacade $blogCategoryFacade, protected readonly BlogArticleElasticsearchFacade $blogArticleElasticsearchFacade, + protected readonly HreflangLinksFacade $hreflangLinksFacade, ) { } @@ -69,6 +72,9 @@ protected function map(): array 'articlesTotalCount' => function (BlogCategory $blogCategory) { return $this->blogArticleElasticsearchFacade->getByBlogCategoryTotalCount($blogCategory); }, + 'hreflangLinks' => function (BlogCategory $blogCategory) { + return $this->hreflangLinksFacade->getForBlogCategory($blogCategory, $this->domain->getId()); + }, ], ]; } diff --git a/src/Resources/config/graphql-types/BlogCategoryDecorator.types.yaml b/src/Resources/config/graphql-types/BlogCategoryDecorator.types.yaml index 1bbee88d83..d266ea4bb6 100644 --- a/src/Resources/config/graphql-types/BlogCategoryDecorator.types.yaml +++ b/src/Resources/config/graphql-types/BlogCategoryDecorator.types.yaml @@ -5,6 +5,7 @@ BlogCategoryDecorator: interfaces: - 'Breadcrumb' - 'Slug' + - 'Hreflang' fields: uuid: type: "Uuid!" @@ -51,3 +52,6 @@ BlogCategoryDecorator: articlesTotalCount: type: "Int!" description: "Total count of blog articles in this category" + hreflangLinks: + type: "[HreflangLink!]!" + description: "Alternate links for hreflang meta tags" From 6abaaef9b25967273d90f561fe70cb924ff993c9 Mon Sep 17 00:00:00 2001 From: Martin Grossmann Date: Mon, 8 Jan 2024 15:51:11 +0100 Subject: [PATCH 6/7] move seo pages from project-base to the framework and frontend-api packages --- .../Resolver/Image/SeoPageImagesQuery.php | 24 ++++++++++ .../Exception/SeoPageNotFoundUserError.php | 21 +++++++++ src/Model/Resolver/SeoPage/SeoPageQuery.php | 44 +++++++++++++++++++ .../Resolver/SeoPage/SeoPageResolverMap.php | 36 +++++++++++++++ .../graphql-types/SeoPageDecorator.types.yaml | 25 +++++++++++ 5 files changed, 150 insertions(+) create mode 100644 src/Model/Resolver/Image/SeoPageImagesQuery.php create mode 100644 src/Model/Resolver/SeoPage/Exception/SeoPageNotFoundUserError.php create mode 100644 src/Model/Resolver/SeoPage/SeoPageQuery.php create mode 100644 src/Model/Resolver/SeoPage/SeoPageResolverMap.php create mode 100644 src/Resources/config/graphql-types/SeoPageDecorator.types.yaml diff --git a/src/Model/Resolver/Image/SeoPageImagesQuery.php b/src/Model/Resolver/Image/SeoPageImagesQuery.php new file mode 100644 index 0000000000..5547a170f6 --- /dev/null +++ b/src/Model/Resolver/Image/SeoPageImagesQuery.php @@ -0,0 +1,24 @@ +mainImageByEntityPromiseQuery( + $seoPage, + SeoPageFacade::IMAGE_TYPE_OG, + ); + } +} diff --git a/src/Model/Resolver/SeoPage/Exception/SeoPageNotFoundUserError.php b/src/Model/Resolver/SeoPage/Exception/SeoPageNotFoundUserError.php new file mode 100644 index 0000000000..3bbd78040d --- /dev/null +++ b/src/Model/Resolver/SeoPage/Exception/SeoPageNotFoundUserError.php @@ -0,0 +1,21 @@ +domain->getId(); + + try { + $slug = SeoPageSlugTransformer::transformFriendlyUrlToSeoPageSlug($pageSlug); + $seoPage = $this->seoPageFacade->getByDomainIdAndPageSlug($domainId, $slug); + } catch (SeoPageNotFoundException $seoPageNotFoundException) { + throw new SeoPageNotFoundUserError($seoPageNotFoundException->getMessage()); + } + + return $seoPage; + } +} diff --git a/src/Model/Resolver/SeoPage/SeoPageResolverMap.php b/src/Model/Resolver/SeoPage/SeoPageResolverMap.php new file mode 100644 index 0000000000..5d681cddaf --- /dev/null +++ b/src/Model/Resolver/SeoPage/SeoPageResolverMap.php @@ -0,0 +1,36 @@ + [ + 'title' => fn (SeoPage $seoPage) => $seoPage->getSeoTitle($this->domain->getId()), + 'metaDescription' => fn (SeoPage $seoPage) => $seoPage->getSeoMetaDescription($this->domain->getId()), + 'canonicalUrl' => fn (SeoPage $seoPage) => $seoPage->getCanonicalUrl($this->domain->getId()), + 'ogTitle' => fn (SeoPage $seoPage) => $seoPage->getSeoOgTitle($this->domain->getId()), + 'ogDescription' => fn (SeoPage $seoPage) => $seoPage->getSeoOgDescription($this->domain->getId()), + ], + ]; + } +} diff --git a/src/Resources/config/graphql-types/SeoPageDecorator.types.yaml b/src/Resources/config/graphql-types/SeoPageDecorator.types.yaml new file mode 100644 index 0000000000..8f668e8d03 --- /dev/null +++ b/src/Resources/config/graphql-types/SeoPageDecorator.types.yaml @@ -0,0 +1,25 @@ +SeoPageDecorator: + type: object + decorator: true + config: + description: "Represents SEO settings for specific page" + fields: + title: + type: "String" + description: "Document's title that is shown in a browser's title" + metaDescription: + type: "String" + description: "Description for meta tag" + canonicalUrl: + type: "String" + description: "Page's canonical link" + ogTitle: + type: "String" + description: "Title for og:title meta tag" + ogDescription: + type: "String" + description: "Description for og:description meta tag" + ogImage: + type: "Image" + description: "Image for og image meta tag by params" + resolve: '@=query("ogImageBySeoPageQuery", value)' From 525fbb10c95e14c0cd23d7296acd0f9309a21114 Mon Sep 17 00:00:00 2001 From: Martin Grossmann Date: Mon, 8 Jan 2024 16:05:43 +0100 Subject: [PATCH 7/7] seo pages now can return hreflang links --- src/Model/Resolver/SeoPage/SeoPageResolverMap.php | 4 ++++ .../config/graphql-types/SeoPageDecorator.types.yaml | 5 +++++ 2 files changed, 9 insertions(+) diff --git a/src/Model/Resolver/SeoPage/SeoPageResolverMap.php b/src/Model/Resolver/SeoPage/SeoPageResolverMap.php index 5d681cddaf..9d9d50c1eb 100644 --- a/src/Model/Resolver/SeoPage/SeoPageResolverMap.php +++ b/src/Model/Resolver/SeoPage/SeoPageResolverMap.php @@ -6,15 +6,18 @@ use Overblog\GraphQLBundle\Resolver\ResolverMap; use Shopsys\FrameworkBundle\Component\Domain\Domain; +use Shopsys\FrameworkBundle\Model\Seo\HreflangLinksFacade; use Shopsys\FrameworkBundle\Model\Seo\Page\SeoPage; class SeoPageResolverMap extends ResolverMap { /** * @param \Shopsys\FrameworkBundle\Component\Domain\Domain $domain + * @param \Shopsys\FrameworkBundle\Model\Seo\HreflangLinksFacade $hreflangLinksFacade */ public function __construct( protected readonly Domain $domain, + protected readonly HreflangLinksFacade $hreflangLinksFacade, ) { } @@ -30,6 +33,7 @@ protected function map(): array 'canonicalUrl' => fn (SeoPage $seoPage) => $seoPage->getCanonicalUrl($this->domain->getId()), 'ogTitle' => fn (SeoPage $seoPage) => $seoPage->getSeoOgTitle($this->domain->getId()), 'ogDescription' => fn (SeoPage $seoPage) => $seoPage->getSeoOgDescription($this->domain->getId()), + 'hreflangLinks' => fn (SeoPage $seoPage) => $this->hreflangLinksFacade->getForSeoPage($seoPage, $this->domain->getId()), ], ]; } diff --git a/src/Resources/config/graphql-types/SeoPageDecorator.types.yaml b/src/Resources/config/graphql-types/SeoPageDecorator.types.yaml index 8f668e8d03..64344c371b 100644 --- a/src/Resources/config/graphql-types/SeoPageDecorator.types.yaml +++ b/src/Resources/config/graphql-types/SeoPageDecorator.types.yaml @@ -2,6 +2,8 @@ SeoPageDecorator: type: object decorator: true config: + interfaces: + - "Hreflang" description: "Represents SEO settings for specific page" fields: title: @@ -23,3 +25,6 @@ SeoPageDecorator: type: "Image" description: "Image for og image meta tag by params" resolve: '@=query("ogImageBySeoPageQuery", value)' + hreflangLinks: + type: "[HreflangLink!]!" + description: "Alternate links for hreflang meta tags"