The Fragment Conundrum
Lessons Learned with Optimizely SaaS
Optimizely SaaS brings big benefits to content teams—simplified deployment, streamlined updates, and the promise of a more user-friendly Visual Builder. However, it also introduces new challenges for developers, not least around GraphQL fragments and the flat structure that replaces traditional inheritance. Fortunately, the Optimizely team asked for my personal input on the solution, and there’s a lot to look forward to.
Why Fragments Matter More Than Ever
What are fragments?
They’re reusable parts of GraphQL queries, letting you define common fields once and apply them to any type. With SaaS, fragments effectively replace inheritance-based patterns like SitePageData
. For instance:
fragment SEOFields on StartPage {
metaTitle
metaDescription
metaKeywords
}
query GetPage {
_Experience(limit: 1) {
...SEOFields
content
}
}
Rather than automatically inheriting from a base class, we define SEO fields on each page type. It might feel repetitive at first, but it can also be quite flexible once you get used to it.
Embracing the Visual Builder
Optimizely’s new Visual Builder uses blocks in place of elements, so you’ll see more granular content structures—rows, columns, composition nodes, etc. Each block has its own fragment, allowing for powerful customisation in how content is displayed:
fragment ElementNode on CompositionComponentNode {
displayName
nodeType
displaySettings {
key
value
}
component {
...ButtonBlockFragment
...CardBlockFragment
}
}
Yes, it’s a lot more fragments. But from a content editor’s point of view, it opens up lots of possibilities for mixing and matching reusable components.
The Global Search Hurdle
One challenge we’ve run into is the lack of a true “inheritance” model that makes searching across multiple page types straightforward. Right now, if you want to query everything with a single request, you’re a bit stuck—each page type is standalone in GraphQL. Here’s the good news, though: Optimizely personally reached out to me to help shape a solution.
They’re developing a feature—tentatively called “interfaces”—which will let us define shared fields once and query them globally. It’s still in the works, but the fact that they asked me for direct feedback and are actively acting on it shows how quickly the platform is evolving in response to real-world needs.
Strawberry Shake vs. GraphQL.NET
Optimizely recommends Strawberry Shake to generate DTOs, but it can get messy with complex queries full of fragments. After some trial, we pivoted to GraphQL.NET, which provides manual control over DTOs:
var query = queryService.GetQueries(
"ButtonBlock",
"ColumnNode",
"CompositionNode",
...
"GetPageByUrl"
);
The upside is cleaner code and less friction when working with multiple fragments in separate files. Sure, it’s a bit more manual, but that manual approach pays off in clarity and maintainability.
Looking Ahead
Despite the current flat structure, I’m excited about what’s coming next:
- Interfaces: A brand-new feature that will bring genuine inheritance capabilities into SaaS, making global search and shared fields a breeze.
- Ongoing Collaboration: The Optimizely team has been open to developer feedback, and our direct involvement ensures any solution will address real-world pain points.
- Continual Improvement: As more developers adopt SaaS, we’ll see steady enhancements to block-based editing, GraphQL support, and performance.
In short, the transition to SaaS is a big shift, but one that’s already bearing fruit for content editors—and soon, for devs too. If you’re feeling overwhelmed by fragments, know that updates are on the horizon that should smooth out many of these quirks.
Ready to Chat?
If you’ve got your own experiences to share or want to dig deeper into GraphQL with Optimizely SaaS, I’d love to talk. After all, we’re shaping these solutions together.
Andy Blyth
Andy Blyth, an Optimizely MVP (OMVP) and Technical Architect at 26 DX with a keen interest in martial arts, occasionally ventures into blogging when memory serves.
