Migration to 14.0
Breaking change: URL identifier unification + type renames.
@doswiftly/storefront-operations@14.0.0 + @doswiftly/storefront-sdk@14.0.0 ujednolicają nazewnictwo do handle (poprzednio mix slug/handle) i renamują typy Brand/BrandSummary dla clarity.
Przed update przeczytaj Naming Conventions.
TL;DR
slugfield →handlena 9 GraphQL typach (Category, Brand, BlogPost, BlogCategory, BlogTag, LoyaltyReward, ProductAttributeDefinition, CategoryFilterOption, BrandFilterValue)BrandSummaryObjectType →BrandBrand(shop branding) →ShopBrand- Query args
slug→handle(Category, BlogPost, BlogPosts)
Field rename — przed i po
Category
# Przed (13.x)
query { category(slug: "figurki") { id slug name } }
# Po (14.0)
query { category(handle: "figurki") { id handle name } }
Brand (canonical product brand entity)
# Przed (13.x)
fragment ProductCard on Product {
brand { id name slug logo } # BrandSummary type
}
query { products(filters: [{ brand: { slug: "funko" } }]) { ... } }
# Po (14.0)
fragment ProductCard on Product {
brand { id name handle logo } # Brand type (renamed)
}
query { products(filters: [{ brand: { handle: "funko" } }]) { ... } }
Blog
# Przed (13.x)
query BlogPosts($categorySlug: String, $tagSlug: String) {
blogPosts(categorySlug: $categorySlug, tagSlug: $tagSlug) { ... }
}
query BlogPost($slug: String) { blogPost(slug: $slug) { slug title } }
# Po (14.0)
query BlogPosts($categoryHandle: String, $tagHandle: String) {
blogPosts(categoryHandle: $categoryHandle, tagHandle: $tagHandle) { ... }
}
query BlogPost($handle: String) { blogPost(handle: $handle) { handle title } }
MenuItem resource union
# Przed (13.x)
fragment MenuItem on MenuItem {
resource {
__typename
... on Category { id slug name }
... on BrandSummary { id slug name logo } # type was BrandSummary
}
}
# Po (14.0)
fragment MenuItem on MenuItem {
resource {
__typename
... on Category { id handle name }
... on Brand { id handle name logo } # renamed from BrandSummary
}
}
Shop branding
# Przed (13.x)
query Shop {
shop {
brand { logo squareLogo slogan colors { primary { background } } }
# type was Brand (shop branding metadata)
}
}
# Po (14.0)
# Same query — type renamed under the hood (Brand → ShopBrand).
# Storefronts using only field selection (no __typename) work unchanged.
# Codegen-generated TypeScript types will reflect ShopBrand instead of Brand.
Migration checklist
pnpm update @doswiftly/storefront-operations@^14.0.0 @doswiftly/storefront-sdk@^14.0.0- Run codegen w storefroncie (
pnpm codegenlub equivalent) - Fix TypeScript errors — codegen pokaże każde miejsce:
BrandSummary→Brandw generated typesBrand(shop branding) →ShopBrandw generated types.slug→.handlena response data (9 typów wymienionych w TL;DR)
- Update GraphQL fragments selectingu renamed fields
- Replace
{ brand: { slug } }filter input →{ brand: { handle } } - Replace BlogPosts query args
categorySlug/tagSlug→categoryHandle/tagHandle - Re-run codegen, sprawdź zero errors
- Test scenarios:
- Category page navigation
- Brand filter na product listing
- Blog post by handle
- Menu rendering (resource union switching)
- Shop branding (logo, colors)
Dlaczego BREAKING
slug vs handle mix w schema rozproszył convention. Brand vs BrandSummary mylił: pełen Brand (canonical entity) nie istniał, tylko BrandSummary (sugerując że gdzieś jest pełen). Plus shop branding Brand blokował nazwę dla product entity.
Zero gotowych storefrontów w produkcji → bezpieczne BREAKING. Spójna konwencja od początku > późniejsze additive aliases + deprecation cycles.
See Also
- Naming conventions — pełna konwencja
- API reference