Let's be honest: when the data structure is more complex than a blog with news — a product catalog with multidimensional characteristics, multilingualism, various content types — standard CMS reach their limits. Craft CMS handles such tasks at the architecture level, not through plugins. We have been developing sites on Craft CMS for many years, with 8+ years in the niche and 50+ completed projects. Starting from $5,000 for a basic corporate site, typical projects range $10,000–$30,000, saving 20–40% vs custom development.
Craft CMS is a PHP/Yii-based CMS with the official source code on GitHub, running on MySQL or PostgreSQL. It stands out with a flexible field system, powerful Twig templating engine, built-in multisite and localization capabilities. It occupies a niche between WordPress (too limited for complex structures) and fully custom solutions — and in this niche it outperforms any other solution in 80% of cases. For example, Craft CMS loads pages up to 3x faster than WordPress for similar content density.
Why Craft CMS for a Custom Catalog
Matrix Fields — content blocks of arbitrary structure inside a field, similar to WordPress Gutenberg but with code, not a UI builder. They let you build a page builder without plugins. Compare: in WordPress you'd need ACF + a bundle of plugins; in Craft, this is a native feature.
Sections — three types: Channel (blog, news), Structure (page hierarchy), Single (single pages). Each Section has its own Entry Types with different field sets.
Relations — native bidirectional links between entries of any type. Live Preview — editors see changes in real time in an iframe with the actual page of the site.
In a typical project, we design the Content Model at the first stage. The model includes the structure of sections and their fields. For example, for a corporate site:
Sections: ├── Homepage (Single) │ └── Entry Type: homepage │ └── Fields: hero (Matrix), about (Matrix), stats (Table) ├── Services (Structure) │ └── Entry Type: service │ └── Fields: intro (Text), features (Matrix), cta (Object) ├── Blog (Channel) │ ├── Entry Type: article │ │ └── Fields: body (Matrix), author (Users), tags (Tags) │ └── Entry Type: video │ └── Fields: videoUrl (URL), transcript (Redactor) └── Team (Channel) └── Entry Type: teamMember └── Fields: role (Text), bio (Redactor), photo (Assets) Example Content Model for an online store
Includes sections: Catalog (Structure with products and categories), Orders (Channel), Customers (Users). Each product has Matrix fields: characteristics, reviews, gallery. Relations are used to link products to categories and orders.Accelerating Development with Matrix Fields
A Matrix Field contains blocks of different types. The pageContent field example with five block types allows flexible page construction without extra code. In a Twig template, blocks are handled via a switch, giving full control over the layout:
{% for block in entry.pageContent.all() %} {% switch block.type %} {% case "richText" %} <div class="prose">{{ block.body }}</div> {% case "imageBlock" %} <figure class="image-block align-{{ block.alignment }}"> {% set image = block.image.one() %} {% if image %} <img src="{{ image.getUrl('large') }}" alt="{{ image.alt }}" width="{{ image.width }}" height="{{ image.height }}"> {% if block.caption %} <figcaption>{{ block.caption }}</figcaption> {% endif %} {% endif %} </figure> {% case "cta" %} <div class="cta-block"> <h3>{{ block.title }}</h3> <p>{{ block.text }}</p> <a href="{{ block.buttonUrl }}" class="btn">{{ block.buttonLabel }}</a> </div> {% case "gallery" %} <div class="gallery cols-{{ block.columns }}"> {% for image in block.images.all() %} <img src="{{ image.getUrl('medium') }}" alt="{{ image.alt }}"> {% endfor %} </div> {% endswitch %} {% endfor %} How Does GraphQL Expand Craft CMS Capabilities?
Craft CMS provides a built-in GraphQL API, allowing flexible content management from external systems. For example, you can query only the needed fields, use fragments, and combine data from different sections. This is especially useful for JAMstack architectures and mobile applications. The API supports authorization and caching, making it production-ready. Enterprise projects often use GraphQL for integration with headless frontends.
What Is Eager Loading and Why Is It Important?
Twig templates use ElementQuery for filtering and pagination. Example of outputting latest posts:
{# Latest posts with pagination #} {% set query = craft.entries() .section('blog') .type('article') .status('live') .orderBy('postDate desc') .limit(12) %} {% set totalPosts = query.count() %} {% set posts = query.offset(pageInfo.offset).all() %} {% for post in posts %} {% include '_components/post-card' with { post: post } %} {% endfor %} {% if pageInfo.totalPages > 1 %} {% include '_components/pagination' %} {% endif %} For performance, use Eager Loading (with) to avoid N+1 queries, which can increase server load up to 5x per page. On one project, we reduced page generation time from 2.3 s to 0.4 s by applying with for related authors and images.
Image Transforms
Craft uses Named Transforms to generate optimized copies of images. You can set WebP format, 85% quality, and multiple sizes for responsive images. For instance, for a hero image we use three sizes: 800w, 1600w, and 2400w with crop mode. This reduces data transfer by 30–50%.
{# Transforms — Named Transforms or inline #} {% set transform = { width: 1200, height: 630, mode: 'crop', position: 'center-center', format: 'webp', quality: 85 } %} <picture> <source srcset="{{ entry.heroImage.one().getUrl({ width: 800, format: 'webp' }) }} 800w, {{ entry.heroImage.one().getUrl({ width: 1600, format: 'webp' }) }} 1600w" type="image/webp"> <img src="{{ entry.heroImage.one().getUrl(transform) }}" alt="Craft CMS development project" loading="lazy"> </picture> Ecosystem Plugins
| Plugin | Purpose |
|---|---|
| SEOmatic | SEO meta, OpenGraph, Schema.org, Sitemap |
| Redactor | Rich text editor |
| CKEditor | Alternative rich text |
| Feed Me | Import data from RSS/XML/CSV |
| Commerce | Full-fledged online store |
| Formie | Form builder |
| Blitz | Static caching (analog of Full Page Cache) |
| Vite | Vite integration for assets |
Common Mistakes When Working with Craft CMS
- N+1 queries in Twig loops — use
withfor Eager Loading. - Incorrect permissions for the
storagefolder — configurechmodimmediately after installation. - Ignoring caching: Blitz or Redis is mandatory for production.
- Overcomplicating Matrix fields — design Content Model based on real needs.
Project Workflow
- Content audit and Content Model design — define content types, fields, relationships. Create mapping.
- Craft setup and structure — install, create sections, entry types, matrix fields.
- Develop Twig templates — build blocks, layouts, partials. Optimize queries.
- Plugin integration — SEO, caching, forms, import.
- Testing and deployment — check on staging, deploy to production.
What's Included in Deliverables
- Documentation on Content Model and instructions for editors
- Access to admin panel and repository
- Team training (2-3 hours)
- Code warranty and support for 30 days
Development Timelines
| Stage | Time |
|---|---|
| Installation, setup, section structure | 1-2 days |
| Content Model (fields, Matrix) | 2-3 days |
| Twig templates | 3-7 days |
| Plugins (SEO, forms, etc.) | 1-2 days |
| Deployment + staging | 1 day |
| Corporate site (10-15 pages) | 10-15 days |
| Complex portal | 4-8 weeks |
We'll evaluate your project in 1 day — contact us for a consultation on Craft CMS implementation. Order turnkey development with a quality guarantee. Get an individual cost and timeline estimate.







