Przejdź do głównej zawartości

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

  • slug field → handle na 9 GraphQL typach (Category, Brand, BlogPost, BlogCategory, BlogTag, LoyaltyReward, ProductAttributeDefinition, CategoryFilterOption, BrandFilterValue)
  • BrandSummary ObjectType → Brand
  • Brand (shop branding) → ShopBrand
  • Query args slughandle (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 } }
# 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

  1. pnpm update @doswiftly/storefront-operations@^14.0.0 @doswiftly/storefront-sdk@^14.0.0
  2. Run codegen w storefroncie (pnpm codegen lub equivalent)
  3. Fix TypeScript errors — codegen pokaże każde miejsce:
    • BrandSummaryBrand w generated types
    • Brand (shop branding) → ShopBrand w generated types
    • .slug.handle na response data (9 typów wymienionych w TL;DR)
  4. Update GraphQL fragments selectingu renamed fields
  5. Replace { brand: { slug } } filter input → { brand: { handle } }
  6. Replace BlogPosts query args categorySlug/tagSlugcategoryHandle/tagHandle
  7. Re-run codegen, sprawdź zero errors
  8. 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