<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Mariusz</title>
    <description>The latest articles on DEV Community by Mariusz (@maniekm).</description>
    <link>https://dev.to/maniekm</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F176138%2Fe2a2effa-5fa9-4622-89e2-bc7baa1dc785.jpg</url>
      <title>DEV Community: Mariusz</title>
      <link>https://dev.to/maniekm</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/maniekm"/>
    <language>en</language>
    <item>
      <title>Best Use Cases of Sanity CMS: Features, Pricing &amp; Implementation Guide</title>
      <dc:creator>Mariusz</dc:creator>
      <pubDate>Sat, 18 Jul 2026 20:08:00 +0000</pubDate>
      <link>https://dev.to/maniekm/best-use-cases-of-sanity-cms-features-pricing-implementation-guide-hmi</link>
      <guid>https://dev.to/maniekm/best-use-cases-of-sanity-cms-features-pricing-implementation-guide-hmi</guid>
      <description>&lt;h2&gt;
  
  
  TL;DR
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Best Sanity CMS use cases include enterprise multilingual websites, media &amp;amp; publishing platforms with high editorial volume, e-commerce product catalogs with dynamic attributes, learning management systems with interactive content, and custom internal tools or dashboards tailored to specific business processes.&lt;/li&gt;
&lt;li&gt;Sanity enables structured content schemas for complex data modeling, real-time collaboration and live editing for distributed teams, GROQ-powered flexible queries that overcome traditional API limitations, integrated asset management with global CDN delivery, and webhooks with ISR revalidation to keep Next.js sites performant and up-to-date.&lt;/li&gt;
&lt;li&gt;Core strengths: clean APIs with GraphQL-like flexibility, instant visual previews, outstanding editor experience, proven scaling for thousands of documents, and significantly lower backend maintenance than &lt;a href="https://pagepro.co/blog/best-cms-development-companies/" rel="noopener noreferrer"&gt;legacy CMS platforms&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Sanity shines in React/Next.js projects that require flexible content modeling, seamless live previews (Draft Mode support), automatic ISR integration, and custom editorial interfaces without rigid templates. It fits teams that prioritize developer freedom (custom plugins, GROQ), editorial efficiency (intuitive interface), and future-proof composable architecture that scales from MVP to enterprise without painful migrations.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://pagepro.co/services/sanity-development" rel="noopener noreferrer"&gt;Sanity&lt;/a&gt; has established itself as a leading player in the &lt;a href="https://pagepro.co/blog/what-is-headless-cms/" rel="noopener noreferrer"&gt;headless CMS&lt;/a&gt; market, holding a meaningful share of the headless CMS space and trust from businesses around the world, per Web Tech Survey's market breakdown (where Sanity trails category leaders like Contentful and Ghost but leads platforms like Prismic). It's a composable content cloud designed to empower both technical and non-technical teams. Sanity best use cases can range from retail websites to knowledge repositories for medical companies. Strong APIs, customizable workflows, and an advanced visual editor make it a great choice for projects that need to be flexible and performant.&lt;/p&gt;

&lt;p&gt;Pagepro has worked on &lt;a href="https://pagepro.co/case-studies/category/sanity" rel="noopener noreferrer"&gt;a wide range of Sanity projects&lt;/a&gt;, like enterprise websites or large-scale applications with custom workflows, and has seen how Sanity improves content management. This article details Sanity's best use cases, exploring the features and advantages that make it the right fit for many types of websites.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Sanity CMS?
&lt;/h2&gt;

&lt;p&gt;Sanity is a &lt;a href="https://www.sanity.io/headless-cms" rel="noopener noreferrer"&gt;headless, API-first content management system&lt;/a&gt; built around the idea that content should be structured data — not locked inside a templated interface. Instead of managing HTML pages, you manage content as discrete, reusable pieces that can be delivered to any frontend, app, or platform through clean APIs.&lt;/p&gt;

&lt;p&gt;At its core, Sanity consists of two parts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://www.sanity.io/studio" rel="noopener noreferrer"&gt;Sanity Studio&lt;/a&gt;&lt;/strong&gt; — a fully customizable content editing environment built in React, where your team creates, edits, and organizes content daily.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://www.sanity.io/docs/datastore" rel="noopener noreferrer"&gt;Content Lake&lt;/a&gt;&lt;/strong&gt; — a cloud-hosted database that stores all your content as structured data and serves it in real time to any channel or platform.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Developers define the content schema in code, which means the editing interface reflects exactly what a project needs — nothing more, nothing less.&lt;/p&gt;

&lt;p&gt;What separates Sanity from traditional CMS platforms like WordPress is where control sits. In WordPress, the CMS owns the presentation layer — themes, page builders, and plugins shape both how content is managed and how it's displayed. In Sanity, the frontend is entirely decoupled. Your content lives in one place and can power a Next.js website, a mobile app, a digital kiosk, or all three simultaneously, without duplicating or reformatting anything.&lt;/p&gt;

&lt;p&gt;Sanity also uses &lt;a href="https://www.sanity.io/docs/groq" rel="noopener noreferrer"&gt;GROQ (Graph-Relational Object Queries)&lt;/a&gt;, its own query language that gives developers fine-grained control over exactly what data gets fetched and in what shape. For teams used to REST APIs returning overfetched payloads, this is a meaningful improvement in both performance and developer experience.&lt;/p&gt;

&lt;p&gt;Here's what makes Sanity stand out from other headless CMS options:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Fully customizable Studio&lt;/strong&gt; — adapt the editing interface to your exact workflow, not the other way around.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Real-time collaboration&lt;/strong&gt; — multiple editors can work on content simultaneously without conflicts.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GROQ querying&lt;/strong&gt; — fetch precisely the data you need, reducing payload size and improving frontend performance.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No vendor lock-in on the frontend&lt;/strong&gt; — connect Sanity to any framework, including Next.js, Astro, or SvelteKit.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scales without migration&lt;/strong&gt; — the same setup that works for an MVP handles enterprise-level content volume.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Sanity has moved well beyond the "developer experiment" stage, with adoption by companies like PUMA, Eurostar, and Morning Brew. It's production-grade infrastructure for content at scale.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Flexibility of Sanity: More Than a Headless CMS
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://pagepro.co/blog/what-is-sanity/" rel="noopener noreferrer"&gt;Sanity&lt;/a&gt; is a Content Operating System that adapts to your business requirements. It has all the features of a modern headless CMS designed for high-traffic environments and demanding enterprise workloads. At the same time, it stays flexible enough for projects of any size.&lt;/p&gt;

&lt;p&gt;What sets it apart from other CMSes is its ability to fit into your workflows. Unlike other solutions, it doesn't force you into rigid templates, plugins, or pre-defined structures.&lt;/p&gt;

&lt;p&gt;While many CMSs focus only on content management, Sanity prioritizes the developer experience, providing exposed APIs that allow you to integrate with any system or tool.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Sanity Studio?
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://www.sanity.io/studio" rel="noopener noreferrer"&gt;Sanity Studio&lt;/a&gt; is a customizable content workspace that lets teams create, edit, and organize content for websites and apps. It's the heart of your content management and where editors collaborate to keep it up to date.&lt;/p&gt;

&lt;p&gt;Since it's React-based, developers can tailor it to your needs, while editors get a clean and fast environment for daily work.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Content Lake in Sanity?
&lt;/h2&gt;

&lt;p&gt;The &lt;a href="https://www.sanity.io/content-lake" rel="noopener noreferrer"&gt;Sanity Content Lake&lt;/a&gt; is a cloud database and central hub where all your content is stored, updated, and delivered in real time. Every piece of content is stored as structured data, so it's easy to query, version, and reuse across websites, apps, and any other digital product.&lt;/p&gt;

&lt;p&gt;Since it's fully managed by Sanity, there's no need to maintain servers or worry about scaling.&lt;/p&gt;

&lt;h2&gt;
  
  
  Top 3 Use Cases for Sanity
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Use Case 1: Use Sanity for Enterprise Websites at Scale
&lt;/h3&gt;

&lt;p&gt;One of the best uses for Sanity is managing content for enterprise websites.&lt;/p&gt;

&lt;p&gt;In one Pagepro project, a global corporation operating across multiple regions with complex content requirements chose Sanity for their website. The site housed multilingual content, region-specific pages, blogs, landing pages, and resource hubs. Each region's team needed tailored access to manage their localized content securely.&lt;/p&gt;

&lt;p&gt;Sanity's multi-language support allowed all this content to reside in a single dataset, saving on costs and simplifying data management. By integrating with Azure Active Directory for SSO, the headless CMS ensured enterprise-grade security and intuitive user management. Sanity's APIs delivered consistent performance, even under heavy traffic.&lt;/p&gt;

&lt;h4&gt;
  
  
  Why Sanity Is the Best Choice for Enterprise Websites
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Multi-Language and Localization Support&lt;/strong&gt; — manage multiple languages and regions in a single dataset to reduce costs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SSO Integration for Security&lt;/strong&gt; — integrate with authentication systems like Azure Active Directory for secure and efficient user management.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Granular Roles and Permissions&lt;/strong&gt; — provide access for regional teams and specific content management tasks.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;High Performance at Scale&lt;/strong&gt; — handle high-traffic demands without compromising site speed or reliability.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Flexible Content Lake&lt;/strong&gt; — adapt to the complex data structures required by global enterprises.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Real-Time Collaboration&lt;/strong&gt; — allow multiple teams to collaborate on content at the same time.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Enhanced Preview Capabilities&lt;/strong&gt; — provide real-time previews for content teams to improve output quality before publishing.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cost Efficiency&lt;/strong&gt; — avoid additional charges for extra datasets.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Use Case 2: Media and Publishing Platforms
&lt;/h3&gt;

&lt;p&gt;One platform Pagepro worked on hosted tens of thousands of structured medical content pieces with complex relationships and compliance needs. Sanity can handle such complexity easily, but in this project it was chosen for its adaptability.&lt;/p&gt;

&lt;p&gt;The client's legal obligations required a longer content history than the default 90 days. Using Sanity's exposed APIs, Pagepro customized history retention to meet compliance standards. Real-time collaboration enabled editors to work simultaneously, and custom workflows allowed every piece of content to pass through proper approval channels.&lt;/p&gt;

&lt;h4&gt;
  
  
  Why Sanity Is the Best Choice for Media and Publishing
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Scalability for High-Volume Content&lt;/strong&gt; — manage thousands of structured content pieces with complex relationships and dependencies.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Custom History Retention&lt;/strong&gt; — extend version history to meet regulatory and compliance requirements.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Real-Time Collaboration&lt;/strong&gt; — enable simultaneous editing by multiple users.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Content Relationships&lt;/strong&gt; — model intricate relationships between content types.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Integration Capabilities&lt;/strong&gt; — use APIs to connect with analytics tools, external platforms, or &lt;a href="https://pagepro.co/services/legacy-system-migration-services" rel="noopener noreferrer"&gt;legacy systems&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Snapshot Generation&lt;/strong&gt; — provide visual documentation of content states for audit or archival purposes.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Use Case 3: Custom Workflows for Large Applications
&lt;/h3&gt;

&lt;p&gt;In another project, Pagepro implemented a workflow where content creation and verification were &lt;a href="https://pagepro.co/services/custom-cms-development" rel="noopener noreferrer"&gt;managed through custom tools&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Integrating AWS Cognito with Sanity enabled a user-friendly admin panel, making the verification process easier without exposing sensitive AWS settings to end-users.&lt;/p&gt;

&lt;p&gt;Another example of customization was the use of AI-powered translation. As soon as a document was published, translations for multiple languages were generated automatically — showing that Sanity supports innovation without the need to build a custom CMS from scratch.&lt;/p&gt;

&lt;h4&gt;
  
  
  Why Sanity Is the Best Choice for Large Applications
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Exposed API for Customization&lt;/strong&gt; — build tailored workflows and integrations to match unique business requirements.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AI-Powered Features&lt;/strong&gt; — automate processes like translations and content repurposing for efficiency.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;User-Friendly Custom Panels&lt;/strong&gt; — simplify workflows with bespoke admin interfaces.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Content Repurposing&lt;/strong&gt; — utilize the same content across multiple platforms, including web, mobile, and more.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Third-Party Integrations&lt;/strong&gt; — connect with external tools like AWS, analytics platforms, and CRMs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Rapid Development&lt;/strong&gt; — use Sanity's tools to create solutions faster than traditional custom CMS builds.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Other Use Cases for Sanity CMS
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Marketing Websites
&lt;/h3&gt;

&lt;p&gt;Sanity Studio is a great asset for marketing websites. Its visual editing experience rivals competitors like Storyblok, letting content creators build visually rich landing pages with reusable content blocks. It's a popular choice for businesses focused on creating dynamic and engaging experiences.&lt;/p&gt;

&lt;h4&gt;
  
  
  Why Sanity Is the Best Choice for Marketing Websites
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Block-Based Content Editing&lt;/strong&gt; — empower content teams to create and reuse predefined blocks for efficiency and consistency.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Enhanced Visual Editor&lt;/strong&gt; — offer previews for a better content creation experience.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Customizable Studio&lt;/strong&gt; — adapt the interface to meet specific branding and workflow needs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Collaboration-Friendly&lt;/strong&gt; — streamline marketing workflows with real-time collaboration and role-based access control.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Integration-Ready&lt;/strong&gt; — connect with CRM, analytics, and marketing automation tools.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  E-Commerce Platforms with Sanity as Headless CMS
&lt;/h3&gt;

&lt;p&gt;Online stores benefit a lot from Sanity's integration with Shopify and other e-commerce tools. It adds value to e-commerce platforms by improving product information management and supporting relationships between products.&lt;/p&gt;

&lt;h4&gt;
  
  
  Why Sanity Is the Best Choice for E-Commerce
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Product Information Management (PIM)&lt;/strong&gt; — centralize product metadata for consistency across channels.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Shopify Integration&lt;/strong&gt; — improve workflows for product descriptions, categories, and relationships.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scalable API&lt;/strong&gt; — handle high-traffic e-commerce demands with no effort.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Customizable Data Models&lt;/strong&gt; — adapt product catalogs to unique business needs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Seamless Multi-Channel Support&lt;/strong&gt; — use the same product data for web, mobile, and other channels.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Learning Platforms
&lt;/h3&gt;

&lt;p&gt;When it comes to managing educational content, Sanity provides the flexibility learning platforms need to implement functions like tracking user progress and delivering multimedia learning materials.&lt;/p&gt;

&lt;h4&gt;
  
  
  Why Sanity Is the Best Choice for Learning Platforms
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Structured Content Management&lt;/strong&gt; — organize lessons, chapters, and quizzes with ease.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Progress Tracking&lt;/strong&gt; — store user progress data to personalize learning experiences.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scalability&lt;/strong&gt; — handle large volumes of content and users.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;API-Driven Delivery&lt;/strong&gt; — integrate with learning management systems (LMS) and mobile apps.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Mobile App Backends
&lt;/h3&gt;

&lt;p&gt;The ability to handle data communications with apps, API focus, and customizability are huge advantages for devs working with Sanity. It's a good option for a mobile application backend.&lt;/p&gt;

&lt;h4&gt;
  
  
  Why Sanity Is the Best Choice for Mobile App Backends
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Fast Setup&lt;/strong&gt; — quickly configure backends for mobile apps.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scalable API&lt;/strong&gt; — ensure consistent performance for high-traffic applications.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Customizable Workflows&lt;/strong&gt; — tailor data structures and workflows to app-specific requirements.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Multi-Platform Compatibility&lt;/strong&gt; — share data across web, iOS, and Android apps.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;Choosing a CMS is a strategic decision, especially for technical leaders managing complex projects or scaling businesses.&lt;/p&gt;

&lt;p&gt;Sanity's impact on content management enables frontend teams to work smarter and faster. The combination of flexibility, strong APIs, and intuitive user experience makes it a great fit for many businesses.&lt;/p&gt;

&lt;p&gt;Sanity use cases range from enterprise websites to e-commerce platforms and custom applications.&lt;/p&gt;

&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;What is Sanity.io?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Sanity.io is a Content Operating System offering teams a flexible way to create, manage, and deliver content to any website or application. It uses structured content stored in the Sanity Content Lake and a customizable editing environment called Sanity Studio. Developers can tailor the entire workflow, while editors get an intuitive platform to update content in real time.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Is Sanity a headless CMS?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Sanity is a headless CMS, but it goes beyond the traditional definition. It functions as a content operating system — providing structured content storage, a fully customizable editing environment, real-time collaboration, and APIs that let you deliver content to any channel. The key difference is that Sanity is designed to adapt to your workflows and data structures, rather than forcing you into predefined templates or rigid content models.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How does Sanity work?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Sanity separates content from your frontend and delivers it as structured data through APIs. Content creators use Sanity Studio to edit and manage content, while the Sanity Content Lake stores everything in the cloud and updates it in real time. Developers then pull that content into websites or apps using Sanity's APIs, giving full control over how and where the content is displayed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What is Sanity used for?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Sanity is used for managing and delivering content across websites, mobile apps, e-commerce platforms, and custom digital products. Its most common use cases include enterprise websites with complex content structures, media and publishing platforms with high editorial volume, and large applications that require custom workflows and integrations. Pagepro has used it across projects ranging from global multilingual websites to medical content platforms with tens of thousands of structured documents.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What is Sanity good for?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Sanity best use cases include marketing sites, e-commerce, blogs, product catalogs, and apps. It's great for any project that needs flexible, well-structured content and a smooth editing experience.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Is Sanity free?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Yes, Sanity has a free plan you can use indefinitely within the included usage limits. It gives access to all core features including real-time collaboration, unlimited content types, and Sanity Studio. For projects that grow beyond those limits — in terms of API requests, bandwidth, or team size — paid plans are available with transparent usage-based pricing.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Is Sanity open source?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Sanity Studio is open source and available on GitHub, which means you can inspect the code, build custom plugins, and contribute to the ecosystem. The Content Lake backend, however, is a managed cloud service and not open source. This distinction matters for teams with strict data residency or self-hosting requirements.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What companies use Sanity?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Sanity is used by companies including PUMA, Morning Brew, Eurostar, and Amplitude — organizations that need structured, scalable content workflows across multiple channels. Its adoption spans industries from retail and media to healthcare and financial services, reflecting its flexibility across very different content requirements.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How much does Sanity cost?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Sanity offers a free plan that covers smaller projects and includes real-time collaboration, unlimited content types, and sufficient API and bandwidth quota for personal projects or low-traffic sites. Paid plans — Growth and Enterprise — unlock higher usage limits, advanced access controls, custom SSO, and dedicated support. Pricing scales with usage rather than seat count, which makes it cost-effective for teams that need flexibility without paying for unused capacity.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Sanity vs WordPress — which should I choose?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The right choice depends on your project's complexity and team setup. WordPress is the better fit for straightforward content sites where non-technical users need a familiar, plugin-rich environment without developer involvement. Sanity is the stronger choice when you need flexible content modeling, multi-channel delivery, real-time collaboration across distributed teams, or a custom editorial interface that matches your specific workflow. For projects built on Next.js or other modern frameworks, Sanity integrates significantly more cleanly than WordPress.&lt;/p&gt;

</description>
      <category>api</category>
      <category>nextjs</category>
      <category>saas</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Migrate from Contentful to Sanity: A Complete Developer Guide</title>
      <dc:creator>Mariusz</dc:creator>
      <pubDate>Sat, 18 Jul 2026 16:58:00 +0000</pubDate>
      <link>https://dev.to/maniekm/migrate-from-contentful-to-sanity-a-complete-developer-guide-1n5a</link>
      <guid>https://dev.to/maniekm/migrate-from-contentful-to-sanity-a-complete-developer-guide-1n5a</guid>
      <description>&lt;h2&gt;
  
  
  Is Contentful Migration the Right Choice for You?
&lt;/h2&gt;

&lt;p&gt;While it has long been a go-to option for teams adopting headless CMS architectures, many organizations have now decided &lt;a href="https://pagepro.co/blog/top-headless-cms-agencies/" rel="noopener noreferrer"&gt;to migrate Contentful to Sanity or other setups&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Companies find &lt;a href="https://pagepro.co/services/contentful-migration-services" rel="noopener noreferrer"&gt;Contentful's structure and pricing more and more restrictive&lt;/a&gt; as their projects scale.&lt;/p&gt;

&lt;p&gt;Limits on content types, rigid field definitions, and the absence of a real pay-as-you-go model often make it difficult to stay flexible without moving into costly enterprise plans.&lt;/p&gt;

&lt;p&gt;For teams focused on speed, content variety, and developer experience, these constraints are a major bottleneck. This is why they choose a shift toward more customizable and scalable alternatives like Sanity.&lt;/p&gt;

&lt;p&gt;This guide covers two ways of migrating a setup from Contentful to &lt;a href="https://pagepro.co/services/sanity-development" rel="noopener noreferrer"&gt;Sanity&lt;/a&gt; — the same SEO-safe migration techniques Pagepro uses in its own projects.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Teams Migrate from Contentful to Sanity
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Contentful Limitations
&lt;/h3&gt;

&lt;p&gt;Contentful's Starter and Lite plans are enough for most small-scale projects. However, once content structures start to grow, so do the constraints. The 25-content-type limit can be a serious obstacle for mid-sized or content-heavy applications. There's no pay-as-you-go option, so scaling up means jumping to a much higher plan instead of paying for incremental usage. Even then, the 50-content-type limit might not be enough in some cases.&lt;/p&gt;

&lt;p&gt;On the development side, content models are bound by predefined field types, fixed validations, and a uniform UI that can't be customized for specific workflows. Rich text editing is also rigid. You can remove formatting options from the toolbar, but not extend or tailor the editor to support things like custom blocks, lists, or reference elements.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why Sanity Is a Better Fit
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://pagepro.co/blog/what-is-sanity/" rel="noopener noreferrer"&gt;Sanity&lt;/a&gt; addresses these pain points with a developer-first approach. Its schema system offers full control over content types, relationships, and validation rules. PortableText replaces Contentful's static rich text editor with a flexible structure that supports custom components and dynamic content.&lt;/p&gt;

&lt;p&gt;Real-time collaboration, customizable editing interfaces, and an API built around GROQ queries make it easier to build, query, and scale complex data models. Combined with a more accommodating pricing structure and strong integration with frameworks like Next.js, Sanity offers the agility that growing teams need without forcing trade-offs.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;We recommend Sanity because it gives both developers and content teams real freedom. You can shape the CMS around your product, not the other way around.&lt;br&gt;
— Rafał Dąbrowski, Developer at Pagepro&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;For a deeper comparison, see &lt;a href="https://pagepro.co/blog/sanity-vs-contentful/" rel="noopener noreferrer"&gt;Headless CMS Guide: Sanity vs Contentful&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Pricing Comparison
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;Pricing as of October 2025.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Sanity stands out for its gradual, transparent pricing. It includes a forever-free tier and paid plans starting at around $15 per user/month for the "Growth" tier.&lt;/p&gt;

&lt;p&gt;Contentful does offer a free plan as well, but as soon as you require any meaningful team collaboration or commercial usage, the first paid tier jumps to around $300/month (or higher) for the next level up. Additionally, if you cross 25 content types or have more than 10k of data, you might have to buy the Lite Space, which costs $850.&lt;/p&gt;

&lt;p&gt;That sharp leap between the free plan and the next level means the decision to "go live" with Contentful comes with a significant budget step that doesn't scale gently. Sanity allows a smoother transition from free to paid, whereas with Contentful, you may face a big budget move early on.&lt;/p&gt;

&lt;h2&gt;
  
  
  Planning a Safe Migration
&lt;/h2&gt;

&lt;p&gt;Migrating from Contentful to Sanity is a structural change that can impact how your content, SEO, and integrations behave. Before running any scripts, decide which migration strategy makes the most sense for your project and learn about its risks.&lt;/p&gt;

&lt;h3&gt;
  
  
  Understand the Risks
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Feature parity.&lt;/strong&gt; Sanity may not have direct replacements for every Contentful plugin, so some marketplace extensions might need to be rebuilt or replaced with custom solutions. In many cases, this becomes an opportunity to clean up unused or outdated features. If a plugin supports a critical part of your workflow, plan for a rebuild.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;SEO and content integrity risks.&lt;/strong&gt; Losing URL structures, internal links, or metadata during transfer can cause ranking drops and broken pages. Redirects, sitemaps, and structured data should be verified early in the process.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Data corruption or loss.&lt;/strong&gt; Complex content models, broken relationships, and rich text formatting can all suffer during conversion, especially with localized data or large asset libraries.&lt;/p&gt;

&lt;p&gt;Migration testing should happen at multiple stages: first with automated checks (to confirm record counts, field types, and assets) and then with manual visual reviews to confirm the content looks identical in Sanity Studio and on the frontend.&lt;/p&gt;

&lt;h3&gt;
  
  
  Choose the Right Migration Path
&lt;/h3&gt;

&lt;p&gt;Once you've assessed the risks, decide how much of the existing structure should carry over. There are two approaches:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Keep your existing structure&lt;/strong&gt; — a fast and low-risk path where you move the current setup to Sanity without major refactoring. Ideal if your main goal is to reduce costs or overcome Contentful's limitations without redesigning your data model.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Rebuild and migrate&lt;/strong&gt; — a more strategic option where you use a custom script to redesign your content structure for long-term flexibility. This approach takes more time but gives you complete control over how your CMS evolves.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you're unsure, start by migrating the current setup using the official tool, confirm stability, and then iterate with schema improvements later. For small to mid-sized projects, this hybrid approach often completes in just a few days, as long as there are no missing dependencies or complex plugin integrations.&lt;/p&gt;

&lt;h2&gt;
  
  
  Option 1: Migrate Using the Official Contentful-to-Sanity CLI
&lt;/h2&gt;

&lt;p&gt;The fastest way to transfer your content from Contentful to Sanity is to use the official CLI tool, &lt;a href="https://www.sanity.io/plugins/contentful-to-sanity" rel="noopener noreferrer"&gt;contentful-to-sanity&lt;/a&gt;. It exports all your data, converts it into Sanity's format, and even generates matching schema files. You can have a working Sanity Studio in minutes.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: Get Your Contentful Credentials
&lt;/h3&gt;

&lt;p&gt;You'll need three API keys from your Contentful account:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Space ID&lt;/strong&gt; — easiest to copy from your project URL (e.g. &lt;code&gt;https://app.contentful.com/spaces/[projectURL]/views/entries&lt;/code&gt;) or find it under &lt;strong&gt;Settings → Space Settings → General Settings&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Content Delivery API token&lt;/strong&gt; — create one in &lt;strong&gt;Settings → API Keys&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Content Management API (CMA) token&lt;/strong&gt; — generate it under &lt;strong&gt;Account Settings → CMA Tokens&lt;/strong&gt;, then click the top-right button to create a new personal access token.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Tip:&lt;/strong&gt; Set your token to expire in 1–30 days. One day is fine for testing, thirty for production.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2: Run the Migration Script
&lt;/h3&gt;

&lt;p&gt;Now that you have your keys, run the CLI command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx contentful-to-sanity@latest &lt;span class="nt"&gt;-s&lt;/span&gt; &amp;lt;space-id&amp;gt; &lt;span class="nt"&gt;-t&lt;/span&gt; &amp;lt;cma-token&amp;gt; &lt;span class="nt"&gt;-a&lt;/span&gt; &amp;lt;Content Delivery API - access token&amp;gt; ./output-path
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If tokens are correct, you'll see logs of the export. A 401 error means one of the keys is invalid.&lt;/p&gt;

&lt;p&gt;After the script finishes, you'll find these files in your output directory:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;contentful.json&lt;/strong&gt; and &lt;strong&gt;contentful.published.json&lt;/strong&gt; — raw exports from Contentful&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;dataset.ndjson&lt;/strong&gt; — data formatted for Sanity import&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;schema.ts&lt;/strong&gt; — auto-generated schema matching your Contentful models&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;At this stage, you're about halfway done. The data is ready, and the schema is mapped.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 3: Create Your Sanity Project
&lt;/h3&gt;

&lt;p&gt;If you don't already have a Sanity account, sign up at sanity.io. Then create a new, clean project:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm create sanity@latest &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--template&lt;/span&gt; clean &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--create-project&lt;/span&gt; &lt;span class="s2"&gt;"Your Project Name"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--dataset&lt;/span&gt; production &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--output-path&lt;/span&gt; my-sanity-project
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Log in when prompted, select "Create new project," choose your organization, and follow the prompts. You should have a clean Sanity project.&lt;/p&gt;

&lt;p&gt;Open your &lt;code&gt;sanity.config&lt;/code&gt; and &lt;code&gt;sanity.cli&lt;/code&gt; files to check your project ID and dataset — you'll need them soon.&lt;/p&gt;

&lt;p&gt;Copy the generated &lt;code&gt;schema.ts&lt;/code&gt; into your &lt;code&gt;schemaTypes&lt;/code&gt; directory with an updated naming, and update your &lt;code&gt;index.ts&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;types&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./schema-contentful&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;schemaTypes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[...&lt;/span&gt;&lt;span class="nx"&gt;types&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That will allow you to add new schemas later without impacting the auto-generated file. Run &lt;code&gt;npm run dev&lt;/code&gt; to preview your new Studio. On the left, you'll see all the content types, empty for now. Remember their names before moving on to data migration.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 4: Import Your Content
&lt;/h3&gt;

&lt;p&gt;Copy &lt;code&gt;dataset.ndjson&lt;/code&gt; into your project and run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx sanity dataset import ./dataset.ndjson
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Select your dataset (default: &lt;code&gt;production&lt;/code&gt;). After the import completes, your entries will appear inside Sanity Studio.&lt;/p&gt;

&lt;p&gt;Next, update your fetching methods in the Next.js app to use the new data source.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 5: Update Your Queries
&lt;/h3&gt;

&lt;p&gt;Replace your Contentful GraphQL API with Sanity's GROQ-based client:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Sanity client configuration&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createClient&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;projectId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;NEXT_PUBLIC_SANITY_PROJECT_ID&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;your-project-id&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;dataset&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;NEXT_PUBLIC_SANITY_DATASET&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;production&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;2024-01-01&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;useCdn&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;NODE_ENV&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;production&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;token&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;SANITY_API_TOKEN&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Convert your GraphQL queries into GROQ queries. If you're struggling with this part, consider using AI to help.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const PAGE_GROQ_FIELDS = `
_id,
_type,
"slug": slug.current,
internalName,
pageName,
seo {
  _id,
  _type,
  name,
  title,
  description,
  "ogImage": image.asset-&amp;gt;url,
  noIndex,
  noFollow
},
topSection[] {
  _id,
  _type,
  _ref,
  internalName,
  // Component CTA
  ...(_type == "componentCta" =&amp;gt; {
    headline,
    subline,
    ctaText,
    targetPage-&amp;gt; {
      "slug": slug.current
    },
    urlParameters,
    colorPalette
  }),
  // Component Duplex
  ...(_type == "componentDuplex" =&amp;gt; {
    containerLayout,
    headline,
    bodyText,
    ctaText,
    targetPage-&amp;gt; {
      "slug": slug.current
    },
    image {
      asset-&amp;gt; {
        url,
        metadata {
          dimensions
        }
      },
      alt
    },
    imageStyle,
    colorPalette
  }),
`
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;-&amp;gt;&lt;/code&gt; sign is very important here. When a field is a reference to another document, by default you only get the reference &lt;code&gt;id&lt;/code&gt;. To resolve it and get real values, you need to use the &lt;code&gt;-&amp;gt;&lt;/code&gt; syntax.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 6: Update the Code
&lt;/h3&gt;

&lt;p&gt;After updating the queries, focus on updating the code where you fetch data. Right now, your setup fetches all posts using GraphQL, the Contentful URL, and access tokens:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getAllPosts&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;isDraftMode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;boolean&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;entries&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetchGraphQL&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s2"&gt;`query {
      pageCollection(where: { slug_exists: true }, preview: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;
        &lt;span class="nx"&gt;isDraftMode&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;true&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;false&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;) {
        items {
          &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;POST_GRAPHQL_FIELDS&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;
        }
      }
    }`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;isDraftMode&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;extractPostEntries&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;entries&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Update it to use your new Sanity client and query:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Get all pages&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getAllPosts&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;isDraftMode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;boolean&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;query&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;groq&lt;/span&gt;&lt;span class="s2"&gt;`*[_type == "page" &amp;amp;&amp;amp; defined(slug.current)] | order(_createdAt desc) {
    &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;PAGE_GROQ_FIELDS&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;
  }`&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;entries&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;query&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;extractPageEntries&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;entries&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Update all the places where you fetch data from Contentful to use Sanity instead. You can still use GraphQL in this scenario — see the &lt;a href="https://www.sanity.io/docs/content-lake/graphql" rel="noopener noreferrer"&gt;official Sanity docs&lt;/a&gt; for setup (it requires deploying the API on every schema change).&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 7: Update the Richtext
&lt;/h3&gt;

&lt;p&gt;Contentful uses its own logic to store and render rich text markdown. Sanity uses its own pattern via the &lt;code&gt;PortableText&lt;/code&gt; component.&lt;/p&gt;

&lt;p&gt;Define the components for each block type and replace the old Markdown renderer:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Image&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;next/image&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;PortableText&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@portabletext/react&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;PortableTextBlock&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@portabletext/types&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;SanityImage&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;alt&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;caption&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;asset&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;_ref&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;_type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;SanityContent&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;_type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;_key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;children&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="nb"&gt;Array&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;_type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;_key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;marks&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;[];&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;markDefs&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="nb"&gt;Array&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;_key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;_type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;href&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;asset&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="nx"&gt;SanityImage&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;url&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;alt&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;PortableTextContent&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;_type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;block&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;image&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;code&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;table&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;list&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;_key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;children&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="nx"&gt;SanityContent&lt;/span&gt;&lt;span class="p"&gt;[];&lt;/span&gt;
  &lt;span class="nl"&gt;markDefs&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="nx"&gt;SanityContent&lt;/span&gt;&lt;span class="p"&gt;[];&lt;/span&gt;
  &lt;span class="nl"&gt;asset&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="nx"&gt;SanityImage&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;url&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;alt&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;code&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;language&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;SanityImageComponent&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="p"&gt;}:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;SanityImage&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"my-6"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Image&lt;/span&gt;
        &lt;span class="na"&gt;src&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
        &lt;span class="na"&gt;alt&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;alt&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
        &lt;span class="na"&gt;width&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;800&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
        &lt;span class="na"&gt;height&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;600&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
        &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"rounded-lg"&lt;/span&gt;
        &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;100%&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;auto&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;caption&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"text-sm text-gray-600 mt-2 text-center italic"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;caption&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;CodeBlock&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="p"&gt;}:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;code&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;language&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;pre&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"bg-gray-100 p-4 rounded-lg overflow-x-auto my-6"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;code&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;`language-&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;language&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;text&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;code&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;code&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;pre&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;components&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;types&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;SanityImageComponent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;code&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;CodeBlock&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;marks&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;link&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="p"&gt;}:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;children&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ReactNode&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;href&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;a&lt;/span&gt;
        &lt;span class="na"&gt;href&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;href&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
        &lt;span class="na"&gt;target&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"_blank"&lt;/span&gt;
        &lt;span class="na"&gt;rel&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"noopener noreferrer"&lt;/span&gt;
        &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"text-blue-600 hover:text-blue-800 underline"&lt;/span&gt;
      &lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;a&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="na"&gt;strong&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;children&lt;/span&gt; &lt;span class="p"&gt;}:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;children&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ReactNode&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;strong&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"font-bold"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;strong&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="na"&gt;em&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;children&lt;/span&gt; &lt;span class="p"&gt;}:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;children&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ReactNode&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;em&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"italic"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;em&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="na"&gt;code&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;children&lt;/span&gt; &lt;span class="p"&gt;}:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;children&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ReactNode&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;code&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"bg-gray-100 px-1 py-0.5 rounded text-sm font-mono"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;code&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;block&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;children&lt;/span&gt; &lt;span class="p"&gt;}:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;children&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ReactNode&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"text-3xl font-bold mb-4 mt-8"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="na"&gt;h2&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;children&lt;/span&gt; &lt;span class="p"&gt;}:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;children&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ReactNode&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h2&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"text-2xl font-bold mb-3 mt-6"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h2&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="na"&gt;h3&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;children&lt;/span&gt; &lt;span class="p"&gt;}:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;children&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ReactNode&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h3&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"text-xl font-bold mb-2 mt-4"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h3&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="na"&gt;h4&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;children&lt;/span&gt; &lt;span class="p"&gt;}:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;children&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ReactNode&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h4&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"text-lg font-bold mb-2 mt-4"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h4&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="na"&gt;normal&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;children&lt;/span&gt; &lt;span class="p"&gt;}:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;children&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ReactNode&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"mb-4 leading-relaxed"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="na"&gt;blockquote&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;children&lt;/span&gt; &lt;span class="p"&gt;}:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;children&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ReactNode&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;blockquote&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"border-l-4 border-gray-300 pl-4 my-4 italic text-gray-700"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;blockquote&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;list&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;bullet&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;children&lt;/span&gt; &lt;span class="p"&gt;}:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;children&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ReactNode&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;ul&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"list-disc list-inside mb-4 space-y-1"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;ul&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="na"&gt;number&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;children&lt;/span&gt; &lt;span class="p"&gt;}:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;children&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ReactNode&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;ol&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"list-decimal list-inside mb-4 space-y-1"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;ol&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;listItem&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;bullet&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;children&lt;/span&gt; &lt;span class="p"&gt;}:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;children&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ReactNode&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;li&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"ml-4"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;li&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="na"&gt;number&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;children&lt;/span&gt; &lt;span class="p"&gt;}:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;children&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ReactNode&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;li&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"ml-4"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;li&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;MarkdownSanity&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;content&lt;/span&gt; &lt;span class="p"&gt;}:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;PortableTextBlock&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"prose prose-lg max-w-none"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;PortableText&lt;/span&gt; &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;components&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;components&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Replace all usages of the old Markdown component:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Before&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"prose"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Markdown&lt;/span&gt; &lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="c1"&gt;// After&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"prose"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;MarkdownSanity&lt;/span&gt; &lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's enough to transfer the CMS and convert your UI to use Sanity data and rich text. From here, focus on extra features like preview plugins (a must-have for editors) — see the &lt;a href="https://www.sanity.io/docs/visual-editing/configuring-the-presentation-tool" rel="noopener noreferrer"&gt;Presentation Tool guide&lt;/a&gt;. Also plan out data revalidation using either Webhooks + &lt;a href="https://www.sanity.io/learn/course/controlling-cached-content-in-next-js/path-based-revalidation" rel="noopener noreferrer"&gt;Revalidate API&lt;/a&gt; or the &lt;a href="https://www.sanity.io/docs/content-lake/live-content-api" rel="noopener noreferrer"&gt;Sanity Live API&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Option 2: Create Your Own CMS Migration Script
&lt;/h2&gt;

&lt;p&gt;If the official CLI tool doesn't work for your project — for example, because you use nonstandard plugins or highly customized content types — you can create your own migration script.&lt;/p&gt;

&lt;p&gt;This path takes longer, but it gives you full control over field mapping, schema design, and data validation.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The custom-script path takes longer, but it gives full control. Once your schemas are right, mapping is easy and the output clean and predictable.&lt;br&gt;
— Rafał Dąbrowski, Developer at Pagepro&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Step 1: Export Data from Contentful
&lt;/h3&gt;

&lt;p&gt;Install the official CLI:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; contentful-cli
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Log in to your Contentful account:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;contentful login
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Export your space data:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;contentful space &lt;span class="nb"&gt;export&lt;/span&gt; &lt;span class="nt"&gt;--space-id&lt;/span&gt; &amp;lt;your-space-id&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This generates a &lt;code&gt;.json&lt;/code&gt; file containing your full space data, including &lt;code&gt;contentTypes&lt;/code&gt;, entries, assets, and localization information. For custom migrations, ignore &lt;code&gt;contentTypes&lt;/code&gt; and focus on &lt;code&gt;entries&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Each entry's &lt;code&gt;sys&lt;/code&gt; object tells you what content type it belongs to, along with its ID and relationships — use this to identify how fields map to your new schema.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2: Define Your Sanity Schemas
&lt;/h3&gt;

&lt;p&gt;In a fresh Sanity project, create schemas that match your data model. Here's an example defining SEO metadata and Page document types:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// ts-nocheck&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;defineField&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;defineType&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;sanity&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;seoType&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;defineType&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;document&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;seo&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;SEO meta tags&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="nf"&gt;defineField&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;name&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;string&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Internal name&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;hidden&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;validation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Rule&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;Rule&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;required&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
    &lt;span class="p"&gt;}),&lt;/span&gt;
    &lt;span class="nf"&gt;defineField&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;title&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;string&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;SEO title&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;hidden&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;This will override the page title in search engine results&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;}),&lt;/span&gt;
    &lt;span class="nf"&gt;defineField&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;description&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;string&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Description&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;hidden&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;This will be displayed in search engine results&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;}),&lt;/span&gt;
    &lt;span class="nf"&gt;defineField&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;image&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;image&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Image&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;hidden&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;}),&lt;/span&gt;
    &lt;span class="nf"&gt;defineField&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;noIndex&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;boolean&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Hide page from search engines (noindex)&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;hidden&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;}),&lt;/span&gt;
    &lt;span class="nf"&gt;defineField&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;noFollow&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;boolean&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Exclude links from search rankings (nofollow)&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;hidden&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;}),&lt;/span&gt;
  &lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;pageType&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;defineType&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;document&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;page&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Page&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Our landing pages&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="nf"&gt;defineField&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;title&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;string&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Title&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;validation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Rule&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;Rule&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;required&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
    &lt;span class="p"&gt;}),&lt;/span&gt;
    &lt;span class="nf"&gt;defineField&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;slug&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;slug&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Slug&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;validation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Rule&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;Rule&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;required&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
    &lt;span class="p"&gt;}),&lt;/span&gt;
    &lt;span class="nf"&gt;defineField&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;seo&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;reference&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;SEO metadata&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;to&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;seo&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}],&lt;/span&gt;
    &lt;span class="p"&gt;}),&lt;/span&gt;
    &lt;span class="nf"&gt;defineField&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;content&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;array&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Content&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;of&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;topicBusinessInfo&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;topicProduct&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;componentProductTable&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="p"&gt;}),&lt;/span&gt;
  &lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Register these schemas in your main configuration file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;pageType&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;seoType&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./schema.fresh&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;schemaTypes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;pageType&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;seoType&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 3: Write Your Migration Script
&lt;/h3&gt;

&lt;p&gt;The script maps data from the old system into Sanity schemas and generates an &lt;code&gt;.ndjson&lt;/code&gt; file for import. First, read the input file, extract the required data, map it to the new schema, then generate the NDJSON output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="cp"&gt;#!/usr/bin/env node
&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;fs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;fs&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;path&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;path&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;CONFIG&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;inputFile&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;contentful-export-8g9vl6174izn-master-2025-10-15T10-17-31.json&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;outputFile&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;pages-migrated.ndjson&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;primaryLocale&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;en-US&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;contentfulData&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;filePath&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;__dirname&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;CONFIG&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;inputFile&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`📖 Reading Contentful export from: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;filePath&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;contentfulData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;readFileSync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;filePath&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;utf8&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;❌ Error reading Contentful export file:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;exit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Filter for page entries&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;pageEntries&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;contentfulData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;entries&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;entry&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
  &lt;span class="nx"&gt;entry&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;sys&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;contentType&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;sys&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;page&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`📄 Found &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;pageEntries&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; page entries`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;convertPageToSanity&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;contentfulPage&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;fields&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;contentfulPage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;primaryLocale&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;CONFIG&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;primaryLocale&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;sanityPage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;_type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;page&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;contentfulPage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;sys&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;pageName&lt;/span&gt;&lt;span class="p"&gt;?.[&lt;/span&gt;&lt;span class="nx"&gt;primaryLocale&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;internalName&lt;/span&gt;&lt;span class="p"&gt;?.[&lt;/span&gt;&lt;span class="nx"&gt;primaryLocale&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Untitled&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;slug&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;_type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;slug&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;current&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;slug&lt;/span&gt;&lt;span class="p"&gt;?.[&lt;/span&gt;&lt;span class="nx"&gt;primaryLocale&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;untitled&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;

  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;seo&lt;/span&gt;&lt;span class="p"&gt;?.[&lt;/span&gt;&lt;span class="nx"&gt;primaryLocale&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;sanityPage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;seo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;_type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;reference&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;_ref&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;seo&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;primaryLocale&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;sys&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="c1"&gt;// TODO: Handle content later / add sections etc&lt;/span&gt;
  &lt;span class="nx"&gt;sanityPage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;content&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;sanityPage&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;sanityPages&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;pageEntries&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;convertPageToSanity&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ndjsonContent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;sanityPages&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;page&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;page&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;outputPath&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;__dirname&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;CONFIG&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;outputFile&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;fs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;writeFileSync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;outputPath&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;ndjsonContent&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`✅ Migration completed!`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`📄 Converted &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;sanityPages&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; pages`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`📁 Output file: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;outputPath&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;❌ Error writing output file:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;exit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;sanityPages&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s1"&gt;📋 Sample converted page:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;sanityPages&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s1"&gt;📊 Field mapping summary:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Contentful → Sanity&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;pageName → title&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;slug → slug.current&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;seo → seo (reference)&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once you have a working base, focus on creating and refining your schemas. Getting the schemas right is the most time-consuming — and important — part of this migration. Once that's done, mapping the data is straightforward.&lt;/p&gt;

&lt;p&gt;When your output looks correct, import it into Sanity and continue with Step 4 from Option 1: updating rich text rendering and adding any plugins you need.&lt;/p&gt;

&lt;p&gt;Some teams use alternative methods, like web scraping, to extract content, if that approach fits their project better.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Migration is a process that rewards preparation. With a clear plan, backups, and a careful approach, anybody can migrate Contentful to Sanity.&lt;/p&gt;

&lt;p&gt;How long it takes depends entirely on your goals. If you're simply moving to Sanity for better flexibility and are happy with your current data model, the process can be very quick. But if you're rebuilding schemas or adding new features, treat it as an opportunity to refine your CMS structure for the long term.&lt;/p&gt;

&lt;p&gt;Above all, never skip testing. Validate your redirects, metadata, and content relationships before the final switch. A few extra rounds of automated and manual checks can save you from downtime, broken links, and SEO drops.&lt;/p&gt;

&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Why Do Companies Migrate Contentful to Sanity?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Teams move from Contentful to Sanity for greater flexibility, customization, and predictable costs. Sanity lets developers define their own content models, add custom input components, and collaborate in real time. It works better for growing teams that need control without the limits of a closed ecosystem.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why is Contentful So Expensive?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The biggest issue with Contentful's pricing is the steep jump between the free and paid tiers. The free plan is generous for individual developers, but for teams only a few content types and users are allowed. The next available plan costs roughly $300/month, plus additional purchases like different types of spaces.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Is Sanity CMS Free?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Yes. Sanity offers a free forever plan suitable for small projects, MVPs, and personal sites. Paid plans start at around $15 per user/month, adding collaboration features, increased API limits, and additional datasets.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How Long Does it Take to Migrate Contentful to Sanity?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Migration time depends on your setup. Using the official CLI tool, a simple project can be moved in a day or two. For larger projects with custom content models, the process can take a few weeks.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What's the Difference Between Using the CLI Tool and Writing a Custom Script for Migration?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The CLI tool is fast and automated — it exports data from Contentful, converts it into Sanity's format, and generates schema files. Writing a custom migration script takes longer but gives you total control: you can redesign schemas, fine-tune data mapping, and decide exactly how relationships and fields are structured.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Can I Migrate Assets, Such as Images and PDFs, from Contentful to Sanity?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Yes. The official CLI handles assets automatically, while a custom script requires you to include them manually using the assets array and Sanity's upload API.&lt;/p&gt;

</description>
      <category>architecture</category>
      <category>saas</category>
      <category>tutorial</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Best CMS in 2026: Sanity vs WordPress</title>
      <dc:creator>Mariusz</dc:creator>
      <pubDate>Fri, 17 Jul 2026 19:21:00 +0000</pubDate>
      <link>https://dev.to/maniekm/best-cms-in-2026-sanity-vs-wordpress-2i3m</link>
      <guid>https://dev.to/maniekm/best-cms-in-2026-sanity-vs-wordpress-2i3m</guid>
      <description>&lt;h2&gt;
  
  
  Sanity and WordPress for Content Management
&lt;/h2&gt;

&lt;p&gt;When building a new website or app, picking a CMS can affect your site's current and future performance. For many teams, the decision comes down to Sanity vs WordPress, and their two very different approaches to content management.&lt;/p&gt;

&lt;p&gt;WordPress offers familiarity, a huge plugin ecosystem, and community support. &lt;a href="https://pagepro.co/services/sanity-development/" rel="noopener noreferrer"&gt;Sanity&lt;/a&gt; has a structured, API-first approach, real-time collaboration, and integration with frameworks like &lt;a href="https://pagepro.co/services/nextjs-development" rel="noopener noreferrer"&gt;Next.js&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Today, we'll compare Sanity and WordPress side by side. This article will cover performance, workflows, costs, ease of use, and security, all to help with choosing the right content management for your project.&lt;/p&gt;

&lt;h2&gt;
  
  
  Headless CMS vs Traditional CMS
&lt;/h2&gt;

&lt;p&gt;Before comparing Sanity and WordPress directly, we need to understand the difference between headless and traditional CMS platforms.&lt;/p&gt;

&lt;p&gt;A traditional CMS like WordPress bundles everything together: content storage, editing interface, design templates, and the frontend that displays your site. With that, launching your site is very easy. However, since your content is coupled to one presentation layer (the website), delivering the same content to an app or a digital display can be tricky.&lt;/p&gt;

&lt;p&gt;A &lt;a href="https://pagepro.co/services/sanity-development/" rel="noopener noreferrer"&gt;headless CMS&lt;/a&gt; separates content management from presentation. Content is stored in a structured way and delivered via APIs, so developers can connect it to any frontend. It allows for more control, but requires expert knowledge for setup and maintenance.&lt;/p&gt;

&lt;h2&gt;
  
  
  Overview of Sanity and WordPress
&lt;/h2&gt;

&lt;h3&gt;
  
  
  What is Sanity CMS?
&lt;/h3&gt;

&lt;p&gt;Sanity is a &lt;a href="https://pagepro.co/blog/what-is-sanity/" rel="noopener noreferrer"&gt;headless content operating system&lt;/a&gt; launched in 2017. Unlike WordPress, which is monolithic, Sanity separates content from presentation, letting you deliver content to any frontend via APIs. It's built for developers who want structured content models, modern workflows, and easy collaboration in content editing.&lt;/p&gt;

&lt;h4&gt;
  
  
  Who Owns Sanity CMS?
&lt;/h4&gt;

&lt;p&gt;Sanity was founded in Oslo, Norway, by Even Westvang, Simen Svale Skogsrud, and Magnus Hillestad. The company, Sanity.io, continues to maintain and develop the platform, which has attracted global clients and investors, including notable brands like Puma, Morning Brew, Cloudflare, and AT&amp;amp;T.&lt;/p&gt;

&lt;h3&gt;
  
  
  Use Cases of Sanity
&lt;/h3&gt;

&lt;p&gt;Sanity is often chosen when teams need a &lt;a href="https://pagepro.co/services/sanity-development/" rel="noopener noreferrer"&gt;developer-first CMS&lt;/a&gt; that's easy to scale, but it also has its uses for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Content-rich websites and apps.&lt;/li&gt;
&lt;li&gt;E-commerce solutions.&lt;/li&gt;
&lt;li&gt;Multi-channel publishing.&lt;/li&gt;
&lt;li&gt;Enterprise content hubs.&lt;/li&gt;
&lt;li&gt;Design-driven websites.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  What is WordPress?
&lt;/h3&gt;

&lt;p&gt;WordPress is a traditional CMS that allows you to create, publish, and manage websites without building everything from scratch. It powers more than 40% of all websites worldwide and holds around 60% of the CMS market share. Its popularity comes from accessibility: with over tens of thousands of free themes and 65,000+ plugins, it offers options to extend features and get a website up and running quickly.&lt;/p&gt;

&lt;h4&gt;
  
  
  Who Developed WordPress?
&lt;/h4&gt;

&lt;p&gt;WordPress was created by Matt Mullenweg and Mike Little in 2003 as a fork of a blogging tool called b2/cafelog. Today, it is an open-source project maintained by a large community of contributors and backed commercially by Automattic.&lt;/p&gt;

&lt;h3&gt;
  
  
  Use Cases of WordPress
&lt;/h3&gt;

&lt;p&gt;WordPress is used for everything from personal blogs to enterprise websites, and its most common uses include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Blogging and publishing.&lt;/li&gt;
&lt;li&gt;Business sites.&lt;/li&gt;
&lt;li&gt;Online stores.&lt;/li&gt;
&lt;li&gt;Membership and community sites.&lt;/li&gt;
&lt;li&gt;Enterprise websites.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What is the Difference Between Sanity vs WordPress for Developers?
&lt;/h2&gt;

&lt;p&gt;Choosing between Sanity and WordPress depends on how you want to build and scale your site over time. Here's how the two compare across the areas that matter most.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;WordPress&lt;/th&gt;
&lt;th&gt;Sanity&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Content Modeling&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Pages, posts, custom post types; rigid for advanced needs&lt;/td&gt;
&lt;td&gt;Schema-based, structured, reusable content&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Pricing&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Free core; costs for hosting, themes, plugins, or VIP&lt;/td&gt;
&lt;td&gt;Free tier; usage-based pricing as projects grow&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Performance&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Depends on hosting, caching, and plugins&lt;/td&gt;
&lt;td&gt;API-first; fast with frameworks like Next.js&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Integrations&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;59k+ plugins and 11k+ themes&lt;/td&gt;
&lt;td&gt;API-driven; integrates with Vercel, Shopify, Algolia&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;DevEx &amp;amp; UX&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Easy for beginners; limited flexibility for devs&lt;/td&gt;
&lt;td&gt;Developer-first; code-defined models, customizable Studio&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Workflows&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Basic publishing; advanced workflows need plugins&lt;/td&gt;
&lt;td&gt;Real-time collaboration, versioning, structured flows&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Security&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Relies on hosting and plugin updates; vulnerable if outdated&lt;/td&gt;
&lt;td&gt;Managed backend; API-based security, smaller attack surface&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Hosting&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Requires separate hosting (shared, managed, or VIP)&lt;/td&gt;
&lt;td&gt;CMS is fully managed; only host the frontend&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Content Modeling
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;WordPress:&lt;/strong&gt; Since it's a traditional CMS, it uses the classic model of pages and posts. It allows for the customization of post types, fields, or plugins. However, its structure is relatively rigid, which can lead to complex workarounds for more advanced needs.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Sanity:&lt;/strong&gt; Its structure is built around schemas, which are sets of rules defining how your content is structured. You can specify exactly what types of content you need, and Sanity enforces that structure. Reusing content across different platforms becomes much easier.&lt;/p&gt;

&lt;h3&gt;
  
  
  Pricing
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;WordPress:&lt;/strong&gt; The core CMS is free and open source. You still need to factor in hosting, premium themes, and paid plugins. The final costs can vary widely depending on whether you run a small site on shared hosting or an enterprise setup on WordPress VIP.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Sanity:&lt;/strong&gt; Has a free plan with limited API requests and users, plus paid plans that scale based on usage (API calls, storage, seats). It can be cost-effective for small projects, but as your traffic or content needs grow, so do the costs.&lt;/p&gt;

&lt;h3&gt;
  
  
  Performance
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;WordPress:&lt;/strong&gt; Runs on PHP and MySQL. Its performance depends heavily on hosting quality, caching plugins, and CDN setup. The right configuration can handle large traffic, but out of the box, WordPress is less optimized.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Sanity:&lt;/strong&gt; Headless by design, it serves content via APIs. When paired with &lt;a href="https://pagepro.co/blog/what-is-nextjs/" rel="noopener noreferrer"&gt;modern frameworks like Next.js&lt;/a&gt;, sites can be pre-rendered for fast load times and excellent Core Web Vitals. Scaling is handled by Sanity's managed infrastructure, so heavy traffic is less of a problem.&lt;/p&gt;

&lt;h3&gt;
  
  
  Integrations
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;WordPress:&lt;/strong&gt; Famous for its plugin ecosystem, and for good reason. WordPress offers thousands of plugins and themes, and you can add SEO tools, payment gateways, and more without custom coding.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Sanity:&lt;/strong&gt; Its flexibility comes from APIs, not prebuilt add-ons. Doesn't use plugins in the same way. Instead, it integrates with developer tools and modern platforms like &lt;a href="https://pagepro.co/blog/optimizing-vercel-hosting-costs/" rel="noopener noreferrer"&gt;Vercel&lt;/a&gt;, Shopify, or Algolia.&lt;/p&gt;

&lt;h3&gt;
  
  
  DevEx &amp;amp; UX
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;WordPress:&lt;/strong&gt; Non-developers find WordPress easy to pick up, thanks to a visual dashboard, WYSIWYG editing, and prebuilt templates. Developers, however, might find customizing beyond themes and plugins cumbersome.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Sanity:&lt;/strong&gt; Geared towards developers. Content models are code-first, and frontends are built with frameworks like React and Next.js. For editors, Sanity Studio offers a smooth experience and a customizable UI. Its initial setup does require some technical expertise.&lt;/p&gt;

&lt;h3&gt;
  
  
  Workflows
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;WordPress:&lt;/strong&gt; Content creation is pretty straightforward, but advanced workflows (approval chains, editorial review, versioning) often require extra plugins. Collaboration features are limited compared to modern tools.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Sanity:&lt;/strong&gt; Focuses a lot on the workflows. Real-time collaboration, version history, and structured editing make it a great choice for larger teams.&lt;/p&gt;

&lt;h3&gt;
  
  
  Security
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;WordPress:&lt;/strong&gt; The security of your WordPress site depends largely on hosting and regular updates. Vulnerabilities often come from outdated plugins.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Sanity:&lt;/strong&gt; Security is centralized rather than plugin-driven. Its headless architecture reduces the attack surface since the CMS doesn't directly serve the website. Content is delivered through secure APIs, and infrastructure is managed by Sanity.&lt;/p&gt;

&lt;h3&gt;
  
  
  Hosting
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;WordPress:&lt;/strong&gt; Requires hosting to run. Since its performance and security can vary depending on your provider, enterprise users often opt for WordPress VIP.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Sanity:&lt;/strong&gt; A fully managed, cloud-based platform, letting you scale as you please. You don't need to worry about hosting the CMS itself; you only host your frontend (e.g., on Vercel or Netlify).&lt;/p&gt;

&lt;h2&gt;
  
  
  Sanity: Pros and Cons
&lt;/h2&gt;

&lt;h3&gt;
  
  
  What Are the Benefits of Using Sanity?
&lt;/h3&gt;

&lt;p&gt;Sanity stands out from other CMS options as a modern, &lt;a href="https://pagepro.co/blog/what-is-headless-cms/" rel="noopener noreferrer"&gt;headless CMS&lt;/a&gt; built for flexibility and performance. Its main advantages include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Flexible content modeling.&lt;/strong&gt; Define custom schemas to structure your content just the way your project requires.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Real-time collaboration.&lt;/strong&gt; Multiple team members can edit content at the same time in Sanity Studio, with updates appearing instantly.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Developer-first approach.&lt;/strong&gt; Sanity allows a seamless integration with third-party tools.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Customizable editor.&lt;/strong&gt; You can tailor the editing environment to match your content needs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Performant and scalable.&lt;/strong&gt; Content is delivered through Sanity's managed Content Lake, optimized for speed and large-scale usage.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reusable content.&lt;/strong&gt; Write once, publish anywhere: websites, mobile apps, IoT, or digital displays.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  What are the Cons of Sanity CMS?
&lt;/h3&gt;

&lt;p&gt;Teams without technical resources can find some aspects of Sanity challenging:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Steep learning curve.&lt;/strong&gt; Setting up schemas and connecting a frontend requires coding knowledge, unlike WordPress's plug-and-play approach.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No traditional themes or plugins.&lt;/strong&gt; You can't just install a theme or plugin to get started. You'll need a developer to build and integrate the feature you want.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scaling costs.&lt;/strong&gt; Sanity's free plan is a great value for small projects, but heavy API usage, large datasets, or many team members can increase monthly costs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hosting split.&lt;/strong&gt; While Sanity hosts the CMS, you must host your frontend separately (e.g., on Vercel or Netlify), which adds an extra step for setup.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Smaller ecosystem.&lt;/strong&gt; Sanity has strong community support, but its ecosystem of third-party integrations is much smaller compared to WordPress.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  WordPress: Pros and Cons
&lt;/h2&gt;

&lt;h3&gt;
  
  
  What Are the Benefits of Using WordPress?
&lt;/h3&gt;

&lt;p&gt;WordPress is one of the most popular content management solutions for modern web development for several reasons:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Free and open-source CMS.&lt;/strong&gt; Anyone can install and use WordPress at no cost, making it accessible for individuals and businesses.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Huge plugin ecosystem.&lt;/strong&gt; With nearly 60,000 plugins, you can add features like SEO optimization, e-commerce (WooCommerce), contact forms, and analytics to your site without custom code.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Thousands of themes.&lt;/strong&gt; Free and premium WordPress themes allow you to get your website running quickly with no experience needed.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ease of use.&lt;/strong&gt; The dashboard and WYSIWYG editor make content management approachable even for non-developers.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Community support.&lt;/strong&gt; WordPress has a massive global community that shares tutorials and support, lowering the barrier for learning.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scalability.&lt;/strong&gt; With the right hosting and setup, WordPress can handle all types of websites, personal blogs, and high-traffic enterprise sites alike.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Disadvantages of a WordPress Site
&lt;/h3&gt;

&lt;p&gt;While WordPress offers plenty of strengths, it also comes with limitations and risks:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Performance issues.&lt;/strong&gt; Out of the box, WordPress might be slow. Performance metrics often rely on caching plugins, CDNs, and optimized hosting.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Security vulnerabilities.&lt;/strong&gt; Its popularity makes it a frequent target for hackers. Many breaches come from outdated themes or plugins.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Plugin dependence.&lt;/strong&gt; Extending functionality often means installing multiple plugins, which can lead to compatibility issues and heavier sites.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Maintenance overhead.&lt;/strong&gt; Regular updates for plugins, themes, and WordPress core are necessary to keep a site secure and stable.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Limited content modeling.&lt;/strong&gt; The post/page/custom post type structure is less flexible compared to modern headless CMS platforms.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Design limitations without coding.&lt;/strong&gt; While themes help, customizing them deeply often requires PHP, HTML, or CSS knowledge.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  When to Choose Sanity vs WordPress
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Use Case&lt;/th&gt;
&lt;th&gt;Choose Sanity if…&lt;/th&gt;
&lt;th&gt;Choose WordPress if…&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Project Type&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Multi-channel platforms, apps, and scalable sites&lt;/td&gt;
&lt;td&gt;Blogs, portfolios, small business sites&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Content Needs&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Structured content, reusable across channels&lt;/td&gt;
&lt;td&gt;Simple pages and posts managed in one place&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Team&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Developer-led teams who can define schemas and build frontends&lt;/td&gt;
&lt;td&gt;Non-technical teams managing content via dashboard&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Performance&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;High performance, Core Web Vitals, and scalability are priorities&lt;/td&gt;
&lt;td&gt;"Good enough" performance with plugins and decent hosting&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Setup&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;You're okay with a steeper setup for long-term flexibility&lt;/td&gt;
&lt;td&gt;You need a fast, out-of-the-box setup with themes/plugins&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Budget&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Prepared for usage-based pricing as you scale&lt;/td&gt;
&lt;td&gt;Relying on free core + low-cost hosting and plugins&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Future Goals&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Long-term growth, custom experiences, future-proof architecture&lt;/td&gt;
&lt;td&gt;Quick launch, affordable maintenance, and community support&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Sanity works best for projects that need flexibility and plan to scale in the future, though it requires some technical expertise. A structured content model, headless architecture, and integrations with frameworks like Next.js make it a great choice for high performance and developer-driven workflows.&lt;/p&gt;

&lt;p&gt;WordPress is a practical choice for blogs, small businesses, and content-focused sites where ease of use matters more than technical flexibility. Free at its core with affordable hosting, WordPress allows for a quick site launch, thanks to the numerous themes and plugins. Non-technical teams can manage sites through their dashboard, with add-ons like WooCommerce or Yoast extending core functionality.&lt;/p&gt;

&lt;h2&gt;
  
  
  WordPress and Sanity: Which CMS is Best for You?
&lt;/h2&gt;

&lt;p&gt;So, which one is the best CMS? Both Sanity and WordPress are powerful platforms, but they serve different needs.&lt;/p&gt;

&lt;p&gt;WordPress is a tried-and-true choice for quick setup, affordability, and ease of use, especially for smaller websites, blogs, or businesses that rely on plugins to extend functionality.&lt;/p&gt;

&lt;p&gt;Sanity, by contrast, offers a modern, developer-first approach and performance built for the future of the web.&lt;/p&gt;

&lt;p&gt;Already on WordPress but feel limited by its performance or extensive plugin setup? Pagepro specializes in helping teams &lt;a href="https://pagepro.co/blog/wordpress-to-sanity-migration-guide/" rel="noopener noreferrer"&gt;migrate from WordPress to modern stacks like Sanity and Next.js&lt;/a&gt; to provide the best performance.&lt;/p&gt;

&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Is Sanity Free or Paid?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Sanity offers both options. It has a free plan with generous limits on users, content, and API calls. For larger projects, users can purchase usage-based paid plans that scale with their traffic, storage, and team needs.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Is WordPress Still The Most Popular CMS?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Yes. As of 2025, WordPress powers about 43% of all websites and holds over 60% of the CMS market share. Its huge ecosystem of plugins, themes, and community support keeps it the most widely adopted CMS in the world.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Which CMS Is Better Than WordPress?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It depends on your needs. WordPress is quick to set up and affordable, making it the favorite of blogs, small businesses, and content-driven sites. Headless CMS platforms like Sanity, Contentful, or Strapi can be better for projects that need multi-channel publishing and modern developer workflows.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Is Sanity Better Than WordPress?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Sanity is better if you need flexibility and developer-first workflows. It also holds a 4.7/5 rating on G2, compared to WordPress's 4.4/5.&lt;/p&gt;

&lt;p&gt;WordPress is better if you want simplicity and speed. It's free at its core, easy for non-technical users, and backed by a massive plugin ecosystem.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Can You Self-Host Sanity CMS?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Sanity Studio is self-hostable, which means you can customize and deploy the editing environment on your own servers or domain. However, its backend, Sanity Content Lake, where all your content is stored and delivered, cannot be self-hosted.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Is Sanity Open-Source?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Sanity is a proprietary platform, but some of its parts are open source. The Sanity Studio framework is open source and customizable, and the core content infrastructure (Sanity Content Lake) is hosted and managed by Sanity.io.&lt;/p&gt;

</description>
      <category>api</category>
      <category>reviews</category>
      <category>webdev</category>
      <category>wordpress</category>
    </item>
    <item>
      <title>Sanity vs Contentful 2026: Which Headless CMS Wins?</title>
      <dc:creator>Mariusz</dc:creator>
      <pubDate>Sun, 12 Jul 2026 22:00:00 +0000</pubDate>
      <link>https://dev.to/maniekm/sanity-vs-contentful-2026-which-headless-cms-wins-5dg8</link>
      <guid>https://dev.to/maniekm/sanity-vs-contentful-2026-which-headless-cms-wins-5dg8</guid>
      <description>&lt;h2&gt;
  
  
  TL;DR
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Sanity and Contentful are modern CMS platforms that allow teams to manage content separately from the frontend application.&lt;/li&gt;
&lt;li&gt;Sanity offers a highly customizable content studio and flexible schema design, giving developers greater control over content structures and editorial workflows.&lt;/li&gt;
&lt;li&gt;Contentful provides a more standardized SaaS CMS environment with ready-to-use infrastructure and tools designed for enterprise content management.&lt;/li&gt;
&lt;li&gt;Both platforms integrate easily with modern frontend frameworks and APIs, making them suitable for headless architectures and multi-channel content delivery.&lt;/li&gt;
&lt;li&gt;The choice between Sanity and Contentful often depends on factors such as customization needs, team workflows, scalability requirements, and pricing models.&lt;/li&gt;
&lt;li&gt;Understanding the differences between these CMS platforms helps teams choose the solution that best supports their content strategy and development stack.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How to Pick the Right CMS in 2025?
&lt;/h2&gt;

&lt;p&gt;When it comes to content solutions, two of the most popular picks in 2025 are Sanity vs Contentful. Both are headless, API-driven platforms, but they differ in flexibility, pricing, and how much control they give you.&lt;/p&gt;

&lt;p&gt;Picking the right CMS solution starts with knowing your team's needs. There is a difference in how developers want to work and the kind of editing experience content teams expect. At the same time, you have to consider how the future platform might scale with your website, and if it's within budget.&lt;/p&gt;

&lt;p&gt;For those trying to choose between Contentful and Sanity, we've prepared a quick comparison of both. Let's find out which is the better choice for you.&lt;/p&gt;

&lt;h2&gt;
  
  
  Features of Contentful vs Sanity
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;Sanity&lt;/th&gt;
&lt;th&gt;Contentful&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Type&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Content Operating System offering schema-as-code flexibility and real-time content collaboration.&lt;/td&gt;
&lt;td&gt;A headless CMS with a structured, UI-first approach.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;G2 Rating&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://www.g2.com/products/sanity/reviews" rel="noopener noreferrer"&gt;4.7/5&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://www.g2.com/products/contentful/reviews" rel="noopener noreferrer"&gt;4.2/5&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Developer Experience&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Sequential editorial workflows with a clear structure.&lt;/td&gt;
&lt;td&gt;Models created via UI or migration scripts. Less flexibility but faster setup for non-technical teams.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Collaborative Editing&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Real-time edits and live updates.&lt;/td&gt;
&lt;td&gt;Studio is fully customizable via React and the structure builder.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Querying &amp;amp; API&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;GROQ (proprietary and highly flexible) plus REST and GraphQL.&lt;/td&gt;
&lt;td&gt;Supports REST and GraphQL.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Customization &amp;amp; UI&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Studio is fully customizable via React and structure builder.&lt;/td&gt;
&lt;td&gt;Limited UI customization. Offers an App Framework.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Performance&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Optimized for low-latency, real-time updates. Uses distributed Content Lake, with optional CDN layer.&lt;/td&gt;
&lt;td&gt;Enterprise-grade performance with global CDN, 99.99% uptime SLA, handles massive API volumes.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Ecosystem&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Open-source ecosystem with strong developer engagement.&lt;/td&gt;
&lt;td&gt;Marketplace with a large partner network and extensive integrations.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Pricing Model&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Usage-based pricing, flexible for smaller projects.&lt;/td&gt;
&lt;td&gt;Fixed-tier pricing that may become costly with scale.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Best For&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Developer-led teams seeking flexibility, real-time content workflows, and custom UIs.&lt;/td&gt;
&lt;td&gt;Teams needing structure, enterprise governance, and predictable scaling.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Use Cases&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;PUMA, Morning Brew, Cloudflare&lt;/td&gt;
&lt;td&gt;KFC, BMW, Notion&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Sanity: Content Operating System
&lt;/h2&gt;

&lt;p&gt;As a Content Operating System, &lt;a href="https://pagepro.co/blog/what-is-sanity/" rel="noopener noreferrer"&gt;Sanity&lt;/a&gt; gives developers complete control over how content is structured, edited, and delivered. Unlike CMSs with rigid, UI-driven models, &lt;a href="https://pagepro.co/blog/top-sanity-agencies/" rel="noopener noreferrer"&gt;Sanity&lt;/a&gt; stores content as structured data defined entirely in code. The content model can evolve alongside the product without fighting platform limitations, and it works seamlessly with frontend solutions like &lt;a href="https://pagepro.co/services/nextjs-development/" rel="noopener noreferrer"&gt;Next.js&lt;/a&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Many frontend developers like that Sanity's schema-as-code fits right into their version control workflow, so content model changes are tracked and reviewed just like any other part of the codebase.&lt;br&gt;
— Rafał Dąbrowski, Pagepro Developer&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Sanity is the leader in the headless CMS industry. It's aimed at teams that want real-time collaboration and the ability to tailor the editing environment to their needs.&lt;/p&gt;

&lt;h3&gt;
  
  
  Sanity Core Features
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Schema-as-code&lt;/strong&gt; which lets you define your entire content structure in JavaScript or TypeScript.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sanity Studio&lt;/strong&gt;, a highly customizable, open-source editing environment built with React.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Real-time editing for multiple users&lt;/strong&gt;. They can edit the same document simultaneously, with changes synced instantly.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Content Lake&lt;/strong&gt;, a cloud-hosted datastore that delivers content updates in milliseconds.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GROQ query language&lt;/strong&gt; with a powerful, flexible syntax for fetching exactly the data you need.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Build or install plugins&lt;/strong&gt; for workflows, integrations, and custom field types.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Built-in image CDN&lt;/strong&gt; with automatic transformations and optimization.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  The Pros of Sanity
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Flexibility&lt;/strong&gt; — Because the schema is defined in code, developers can model and manage content exactly as they need it without working around a UI's constraints.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Real-Time Collaboration&lt;/strong&gt; — Editors see changes instantly, making it easier to work without overwriting.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fully Customizable Studio&lt;/strong&gt; — You can adapt the editing interface to match the project's needs and add custom input components.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Version Control for Content Models&lt;/strong&gt; — Since schemas live in your codebase, they can be tracked, reviewed, and deployed like any other part of the application.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Performance&lt;/strong&gt; — Content Lake delivers low-latency data and supports live updates to the front end.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Plugin Ecosystem&lt;/strong&gt; — Growing library of official and community plugins for analytics, localization, e-commerce, and workflow enhancements.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Generous Free Tier&lt;/strong&gt; — Suitable for prototypes or small sites before scaling up to paid usage.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Cons of Sanity
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Steeper Setup for Non-Developers&lt;/strong&gt; — Without a developer to define schemas, the content platform has no ready-to-use structure.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Learning Curve for GROQ&lt;/strong&gt; — While powerful, Sanity's proprietary query language isn't as widely known as GraphQL, so teams need time to get up to speed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Usage-Based Pricing&lt;/strong&gt; — Costs can spike if you have high traffic, many API requests, or large amounts of stored data.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fewer Turnkey Integrations&lt;/strong&gt; — While the plugin ecosystem is growing, it's smaller than Contentful's established marketplace.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is Sanity.io Used For?
&lt;/h3&gt;

&lt;p&gt;Sanity is widely &lt;a href="https://pagepro.co/blog/best-use-cases-of-sanity/" rel="noopener noreferrer"&gt;used for projects&lt;/a&gt; where content complexity and flexibility are essential:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Multi-platform content delivery&lt;/strong&gt; to push content to websites, apps, and in-store displays from a single source.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Custom editorial workflows&lt;/strong&gt; matching a brand's content process.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sites that need collaborative publishing&lt;/strong&gt;, live dashboards, or apps where content changes need to appear instantly.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Design- and content-rich sites&lt;/strong&gt; that need a CMS to adapt to unique layouts or structures.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Well-known brands like PUMA, Morning Brew, and Cloudflare have used Sanity for projects that require both creative freedom and scalable performance.&lt;/p&gt;

&lt;h2&gt;
  
  
  Contentful: Headless CMS
&lt;/h2&gt;

&lt;p&gt;Contentful is a cloud-native, API-first &lt;a href="https://pagepro.co/blog/what-is-headless-cms/" rel="noopener noreferrer"&gt;headless CMS&lt;/a&gt;, sometimes referred to as a "composable content platform." It decouples content storage from presentation, offering content as JSON data via REST or GraphQL APIs.&lt;/p&gt;

&lt;p&gt;This architecture makes it flexible and channel-agnostic, ideal for modern omnichannel publishing.&lt;/p&gt;

&lt;h3&gt;
  
  
  Contentful Core Features
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;API-first architecture&lt;/strong&gt; with REST and GraphQL endpoints for content delivery.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Structured content modelling&lt;/strong&gt; for defining content types, fields, and relationships.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Role-based permissions&lt;/strong&gt; for editorial governance.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Content versioning&lt;/strong&gt; with history and rollback.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;App Framework and Marketplace&lt;/strong&gt; for integrations with analytics, e-commerce, translation, and marketing tools.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Global CDN&lt;/strong&gt; for fast content delivery worldwide.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  The Pros of Contentful
&lt;/h3&gt;

&lt;p&gt;Contentful has become a go-to choice for many enterprises because it blends the stability of a mature platform with the flexibility of a headless setup. Its features are built to support large teams and high-traffic projects.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Reliability&lt;/strong&gt; — Known for uptime and stability, backed by SLAs and global CDN infrastructure.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Predictable Workflows&lt;/strong&gt; — A structured, UI-driven content model is easy for non-technical editors and marketers to follow, reducing errors in large teams.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Integrated Ecosystem&lt;/strong&gt; — The App Marketplace and strong partner network make it straightforward to connect with third-party services.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Omnichannel&lt;/strong&gt; — The API-first approach lets you push the same content to multiple platforms easily.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Cons of Contentful
&lt;/h3&gt;

&lt;p&gt;Contentful is a great option if you're looking for reliability and governance, but it has some significant trade-offs:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Rigid Content Modelling&lt;/strong&gt; — The structured approach is great for governance but can feel inflexible when requirements change. Introducing a new nested relationship or restructuring content types often requires multiple migration scripts and extensive testing.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Limited Previews&lt;/strong&gt; — Contentful offers a Preview API and a Live Preview SDK, but they require extra setup. Without them, editors can't see draft changes instantly, so feedback loops are slower compared to CMSs with built-in real-time preview.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Workflow Gaps&lt;/strong&gt; — There's no built-in real-time collaborative editing (like Google Docs or Sanity's live editing). Two people editing the same entry risk overwriting each other's changes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;API Rate Limits&lt;/strong&gt; — Build processes, especially in static site generators or large migrations, can hit rate limits. On busy projects, this can cause delays unless you move to a higher-cost plan.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;High Scaling Costs&lt;/strong&gt; — Pricing is tiered by users, locales, and content types. A project might start affordably but become expensive as you add editorial staff, expand into multiple regions, or store more entries.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Learning Curve&lt;/strong&gt; — While editors can pick up the UI quickly, developers must learn Contentful's specific APIs, content modelling patterns, and migration tooling, which adds onboarding time.&lt;/p&gt;

&lt;h3&gt;
  
  
  Which Companies Use Contentful?
&lt;/h3&gt;

&lt;p&gt;Contentful is often chosen for projects where structured governance, scalability, and predictable workflows are more important than extreme flexibility. Examples include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Enterprise-scale websites&lt;/strong&gt; that need strict content structures and localization.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Multi-channel publishing&lt;/strong&gt; to deliver consistent content across websites, mobile apps, kiosks, and other digital touchpoints.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Marketing and campaign sites&lt;/strong&gt; where content needs to be updated quickly without involving developers.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Global brand platforms&lt;/strong&gt; maintaining brand consistency across regions with role-based permissions and approval workflows.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;High-profile organisations, like KFC, BMW, and Notion, rely on Contentful for enterprise-scale and multi-platform content delivery. However, many teams are &lt;a href="https://pagepro.co/blog/contentful-mig" rel="noopener noreferrer"&gt;migrating from Contentful&lt;/a&gt; due to its high costs and rigid architecture.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is the Difference Between Contentful and Sanity?
&lt;/h2&gt;

&lt;p&gt;Both Contentful and Sanity are API-first, headless platforms. However, they approach content management very differently.&lt;/p&gt;

&lt;p&gt;Contentful takes a UI-first, structured approach. You model content types within its dashboard, define fields through the interface, and let non-technical editors work within a predictable, governed environment. This way, onboarding is much easier for large teams and helps to keep content consistent across regions and channels.&lt;/p&gt;

&lt;p&gt;Sanity, on the other hand, is schema-as-code from the ground up. Content models live in the codebase, so developers have complete control over the structure. The Studio editing environment is open-source and fully configurable. The real-time collaboration feature means multiple editors can work on the same content simultaneously without conflicts.&lt;/p&gt;

&lt;p&gt;The result is that Contentful often appeals to enterprises that need predictability and a ready-made editorial interface. Sanity is well-liked by developer and editorial teams looking for flexibility.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sanity vs Contentful Pricing
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;Pricing as of August 2025.&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  What's the Cost of Sanity?
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Free tier&lt;/strong&gt; — up to 20 user seats, 2 roles, 2 public datasets, unlimited content types/locales, real-time collaboration, basic compute/API/asset limits. Generous enough for prototypes, internal tools, or small sites.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Growth: $15/seat/month&lt;/strong&gt; — up to 50 seats, 5 roles, private/public datasets, comments/tasks/content releases, AI Assist features, higher API/bandwidth/asset limits (overages billed separately).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Enterprise: Custom pricing&lt;/strong&gt; — unlimited seats, advanced access control and governance, SSO, SLAs, dedicated support/onboarding/training, media library add-ons.&lt;/p&gt;

&lt;h3&gt;
  
  
  How Much Does Contentful Cost?
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Free tier&lt;/strong&gt; — 10 users, 2 roles, 2 locales, 100K API calls/month, 50 GB/month CDN bandwidth, 1 Starter Space. Suitable for learning, prototyping, or very small sites.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Lite: $300/month&lt;/strong&gt; — 20 users, 3 roles, 3 locales, 1M API calls/month, 100 GB/month CDN bandwidth, comments &amp;amp; task management, scheduled publishing, live collaboration, 1 Starter Space (with option to add 1 Lite Space).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Premium: Custom pricing&lt;/strong&gt; — everything in Lite plus custom users/roles/locales, unlimited API calls, custom CDN bandwidth, enhanced governance/compliance/security, up to 99.99% uptime SLA, dedicated customer success and 24/7 support, unlimited Spaces and advanced features.&lt;/p&gt;

&lt;h3&gt;
  
  
  Pricing Comparison Table
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Plan&lt;/th&gt;
&lt;th&gt;Sanity&lt;/th&gt;
&lt;th&gt;Contentful&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Free&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;20 seats, 2 roles, 2 public datasets, unlimited content types/locales, real-time collaboration&lt;/td&gt;
&lt;td&gt;10 users, 2 roles, 2 locales, 100K API calls/mo, 50 GB CDN, 1 Starter Space&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Mid-Tier&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;$15/seat/mo, up to 50 seats, 5 roles, private/public datasets, comments, tasks, content releases, AI Assist, usage-based overages&lt;/td&gt;
&lt;td&gt;$300/mo, 20 users, 3 roles, 3 locales, 1M API calls/mo, 100 GB CDN, comments, scheduled publishing, live collaboration&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Enterprise&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Custom pricing, unlimited seats, advanced access control, SSO, SLAs, dedicated onboarding/support, media library add-ons&lt;/td&gt;
&lt;td&gt;Custom pricing, unlimited API calls, custom bandwidth, unlimited Spaces, advanced governance, 24/7 support, up to 99.99% SLA&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Pricing Model&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Seat-based pricing + usage-based add-ons&lt;/td&gt;
&lt;td&gt;Fixed-tier pricing with defined limits&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Best For&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Flexible scaling, custom workflows, collaborative editing&lt;/td&gt;
&lt;td&gt;Predictable budgets, strict governance, enterprise-scale delivery&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Monthly Costs of Sanity vs Contentful
&lt;/h3&gt;

&lt;p&gt;The difference in costs between Contentful and Sanity, depending on your needs, can be significant. Pagepro's clients usually need at least 5 users and 30 different content types. Here's how a setup like this compares:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Sanity (Growth Tier):&lt;/strong&gt; 5 users × $15 = $75/month, plus roughly $25 for extra usage → around &lt;strong&gt;$100/month&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Contentful (Lite Tier):&lt;/strong&gt; The free Starter Space covers 25 content types. Going beyond that requires the Lite Space (up to 50 content types), added on top of the Lite Plan: $300 Lite Plan + $850 Lite Space = &lt;strong&gt;$1,150/month&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;For a 5-user, 30-content-type setup, that's a monthly difference of over $1,000 — switching from Contentful to Sanity could save roughly &lt;strong&gt;$12,000 a year&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sanity vs Contentful: Choosing the Right Option
&lt;/h2&gt;

&lt;p&gt;Both Sanity and Contentful are capable, modern platforms; the better choice comes down to your team's needs.&lt;/p&gt;

&lt;h3&gt;
  
  
  Pick Sanity if…
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Full control over content structure through schema-as-code is important.&lt;/li&gt;
&lt;li&gt;Real-time collaboration between editors is a core requirement.&lt;/li&gt;
&lt;li&gt;A fully customizable editing environment is needed to match unique workflows.&lt;/li&gt;
&lt;li&gt;Flexible, usage-based pricing is preferred for smaller projects with room to scale.&lt;/li&gt;
&lt;li&gt;The content model is complex or expected to change frequently.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Choose Contentful if…
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;A ready-to-use, structured editorial environment will speed up adoption for non-technical users.&lt;/li&gt;
&lt;li&gt;Predictable pricing and defined limits outweigh the need for deep customization.&lt;/li&gt;
&lt;li&gt;Large, distributed teams rely on strict governance, roles, and approval workflows.&lt;/li&gt;
&lt;li&gt;Enterprise-grade reliability, global content delivery, and strong SLAs are top priorities.&lt;/li&gt;
&lt;li&gt;A wide ecosystem of integrations and proven enterprise deployments is essential.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In short, Sanity shines when flexibility, customization, and live collaboration matter most, while Contentful excels in structured governance, predictable workflows, and enterprise scalability.&lt;/p&gt;

&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;What Kind of CMS is Contentful?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Contentful is a headless CMS. It stores content in a structured way and delivers it through APIs, allowing developers to use any technology to display that content on websites, apps, or other digital platforms.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Which CMS is Better, Sanity or Contentful?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Sanity is ideal for developer-led projects that need flexibility, real-time collaboration, and a fully customizable editing experience. Contentful works best for larger teams that value a ready-to-use interface, structured governance, and predictable pricing. Both are powerful headless CMS platforms, but the right one comes down to workflow preferences, budget, and long-term scalability.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What is a Headless CMS?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A headless CMS separates the content management back end from the front-end presentation. Content is created and stored in the CMS, then delivered via an API to any channel.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Is Sanity a CMS?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Sanity is a Content Operating System. It offers more customization, real-time collaboration, and schema-as-code content modeling than traditional CMS options.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What's the Difference Between Headless CMS and Content Operating System?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A headless CMS solution focuses on storing and delivering content via APIs. A Content Operating System, like Sanity, does that too but adds deeper customization, real-time collaboration, and the ability to fully control the content model and editing environment.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Is Sanity CMS Open-Source?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Sanity Studio, the editing interface, is open source and can be customized or extended by developers. The hosted Content Lake (where your content is stored and delivered) is not open source.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why is Contentful So Expensive?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Contentful can become costly because pricing increases with the number of users, locales, API calls, and content spaces. Enterprise plans also include advanced features, SLAs, and dedicated support, which add to the price.&lt;/p&gt;

</description>
      <category>architecture</category>
      <category>reviews</category>
      <category>saas</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Strategy for a Successful Legacy System Migration to Next.js</title>
      <dc:creator>Mariusz</dc:creator>
      <pubDate>Fri, 10 Jul 2026 18:08:00 +0000</pubDate>
      <link>https://dev.to/maniekm/strategy-for-a-successful-legacy-system-migration-to-nextjs-5556</link>
      <guid>https://dev.to/maniekm/strategy-for-a-successful-legacy-system-migration-to-nextjs-5556</guid>
      <description>&lt;h1&gt;
  
  
  Strategy for a Successful Legacy System Migration to Next.js
&lt;/h1&gt;

&lt;p&gt;&lt;em&gt;By Joanna Chmiel | December 4, 2025&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Is Replacing a Legacy System with Next.js Worth It?
&lt;/h2&gt;

&lt;p&gt;Many companies reach a point where the legacy software slows the team down more than it helps. Deployments take too long, small changes feel risky, and the system keeps getting harder to maintain. A legacy system migration to &lt;a href="https://pagepro.co/services/nextjs-development" rel="noopener noreferrer"&gt;Next.js&lt;/a&gt; can improve performance, strengthen security, and give your team room to move faster, but the decision has to line up with your business needs.&lt;/p&gt;

&lt;p&gt;That's why this guide walks through the types of legacy system modernization, how to choose the right migration approach, and what a &lt;a href="https://pagepro.co/blog/how-to-make-proper-cms-cms-migration/" rel="noopener noreferrer"&gt;successful migration&lt;/a&gt; actually involves.&lt;/p&gt;

&lt;p&gt;Before we get into the details, let's get clear on what legacy system migration means.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Is Legacy System Migration?
&lt;/h2&gt;

&lt;p&gt;Legacy system migration is the process of moving an application or software from outdated technology to a modern platform. Modern businesses migrate legacy systems to improve performance, enable new workflows, strengthen security, reduce maintenance costs, and support digital transformation.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why Migrate from Outdated Software?
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://pagepro.co/services/legacy-system-migration-services" rel="noopener noreferrer"&gt;Moving off a legacy system&lt;/a&gt; does more than update your tech stack. Done right, it solves three core problems:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Risk reduction&lt;/strong&gt; – Outdated systems are full of security vulnerabilities. They create compliance risks. They put you one incident away from data loss. Modern technology fixes these problems at the foundation.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cost optimization&lt;/strong&gt; – The maintenance costs alone make legacy systems expensive. Add in outdated legacy infrastructure and the developer overhead of working with old code, and modern alternatives start looking cheap.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Future-proofing&lt;/strong&gt; – Want to do cloud migration? Need seamless integration with new platforms? Modern systems give you better compatibility, easier workflows, and improved team productivity without the constant workarounds.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  How Much Does A Legacy System Cost?
&lt;/h3&gt;

&lt;p&gt;Legacy environments rarely show up as a single line item in your budget, which is exactly why they're so expensive. The real cost hides in operational drag that compounds every year.&lt;/p&gt;

&lt;p&gt;A Workday study found that a majority of IT budgets go toward simply keeping existing systems running, leaving only a small share for innovation. Many financial services CTOs say their legacy tech stack is too costly for modern applications, and a similar share of business leaders blame legacy systems for a lack of agility.&lt;/p&gt;

&lt;h3&gt;
  
  
  What Drives Legacy System Costs?
&lt;/h3&gt;

&lt;p&gt;When you analyze the total cost of maintaining legacy systems, you'll notice maintenance work scattered across multiple teams and licensing costs that keep climbing. Infrastructure overhead from outdated technology eats into your budget, while slow release cycles happen because of fragile legacy code that nobody wants to touch. You're constantly applying security patches and compliance updates to stay current.&lt;/p&gt;

&lt;p&gt;These expenses don't show up as "legacy system costs" in your budget. But together, they kill velocity, increase risk, and make modernization harder.&lt;/p&gt;

&lt;h3&gt;
  
  
  How Modernization Reduces Costs
&lt;/h3&gt;

&lt;p&gt;Moving away from legacy platforms changes the economics. You replace unpredictable costs with stable infrastructure and unlock capabilities that old systems can't deliver.&lt;/p&gt;

&lt;p&gt;Modern platforms give you cloud-native scaling and cloud migration flexibility without the architectural gymnastics. They're built for stronger security and easier compliance from the ground up. On the development side, content workflows speed up (especially with platforms like Sanity), performance and SEO improve, and your developer experience gets better, which means faster delivery in general.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If your team is running on WordPress, Gatsby, or a custom stack that's slowing you down, Nexity is the fastest path to a modern &lt;a href="https://pagepro.co/blog/nexity-nextjs-sanity-migration-system/" rel="noopener noreferrer"&gt;Next.js + Sanity&lt;/a&gt; foundation. Pagepro's migration system delivers in 4 weeks — without touching your product roadmap or putting your search rankings at risk. &lt;a href="https://pagepro.co/services/nexity" rel="noopener noreferrer"&gt;Learn more about Nexity →&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Why Migrate to Next.js?
&lt;/h2&gt;

&lt;p&gt;Migrating to &lt;a href="https://pagepro.co/blog/what-is-nextjs/" rel="noopener noreferrer"&gt;Next.js&lt;/a&gt; gives you a modern foundation built for speed, security, and scalability. Teams moving off legacy frontends or older React apps typically see immediate improvements: faster load times, better Core Web Vitals, stronger SEO performance, and fewer infrastructure headaches.&lt;/p&gt;

&lt;p&gt;It also simplifies your stack. Backend logic, frontend UI, and API routes live in one framework instead of being scattered across multiple tools. For organizations modernizing their architecture, Next.js is one of the most reliable ways to future-proof your frontend without business disruptions.&lt;/p&gt;

&lt;h2&gt;
  
  
  Types of Legacy Migrations
&lt;/h2&gt;

&lt;p&gt;Modernization looks different depending on what you're trying to fix. Here are the three most common approaches:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Migration Type&lt;/th&gt;
&lt;th&gt;When to Use It&lt;/th&gt;
&lt;th&gt;Typical Outcomes&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Frontend Migration (to Next.js)&lt;/td&gt;
&lt;td&gt;Legacy UI, poor performance, SEO issues&lt;/td&gt;
&lt;td&gt;Faster load times, better Core Web Vitals, predictable architecture&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CMS Migration (to Sanity)&lt;/td&gt;
&lt;td&gt;Content bottlenecks, poor editorial workflow&lt;/td&gt;
&lt;td&gt;Structured content, real-time collaboration, scalable content model&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Full Legacy Modernization&lt;/td&gt;
&lt;td&gt;Outdated database, monolith, fragile logic&lt;/td&gt;
&lt;td&gt;Cloud-ready architecture, improved security, easier maintenance&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Frontend Migration
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt; Migrating from a legacy application to Next.js.&lt;/p&gt;

&lt;p&gt;This makes sense when performance, SEO, or developer experience has gotten painful. You'll typically see faster page loads, better Core Web Vitals scores, and more predictable architecture. Server-first data handling reduces client-side complexity, and your team stops fighting the framework.&lt;/p&gt;

&lt;h3&gt;
  
  
  CMS Migration
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt; Moving from &lt;a href="https://pagepro.co/services/wordpress-migration" rel="noopener noreferrer"&gt;WordPress&lt;/a&gt; or &lt;a href="https://pagepro.co/services/contentful-migration-services" rel="noopener noreferrer"&gt;Contentful&lt;/a&gt; to Sanity.&lt;/p&gt;

&lt;p&gt;When editors struggle with workflow friction, or your content model can't support what you're building, this type of migration might be what you need. If you need API-first architecture for multi-channel delivery, modern platforms like &lt;a href="https://pagepro.co/blog/what-is-sanity/" rel="noopener noreferrer"&gt;Sanity&lt;/a&gt; give you structured content, real-time collaboration, and flexible APIs that work seamlessly with frameworks like Next.js.&lt;/p&gt;

&lt;h3&gt;
  
  
  Full Legacy System Modernization
&lt;/h3&gt;

&lt;p&gt;A full transfer is the best idea for systems running on outdated databases, monolithic or on-premises architectures, or fragile business logic nobody wants to touch. Full modernization usually means new hosting infrastructure, updated data flows, and consolidating fragmented services into something maintainable.&lt;/p&gt;

&lt;h2&gt;
  
  
  Plan Your Next.js Migration Strategy
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Start With Clear Project Requirements
&lt;/h3&gt;

&lt;p&gt;Before writing any code, consider your modernization strategy. Write down what the project does now and what you need it to do after migration. Cover the basics:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Which pages and routes exist, where data comes from, and what integrations are running?&lt;/li&gt;
&lt;li&gt;How the UI should look, what SEO can't break?&lt;/li&gt;
&lt;li&gt;Where are you planning to host it?&lt;/li&gt;
&lt;li&gt;What performance targets are you aiming for?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This document becomes your reference point for every decision you make during the process and will help you avoid disruptions.&lt;/p&gt;

&lt;h3&gt;
  
  
  Understand the Existing Routing Structure
&lt;/h3&gt;

&lt;p&gt;Next.js uses file-system-based routing, which might work differently from whatever you're using now.&lt;/p&gt;

&lt;p&gt;Create a mapping that shows how your current routes translate to Next.js. Note which pages are static, which routes are dynamic, where you have optional or catch-all paths, how your nested routes work, which routes need protection, and where redirects are required.&lt;/p&gt;

&lt;h4&gt;
  
  
  Common Issues
&lt;/h4&gt;

&lt;p&gt;Converting routes trips people up in predictable ways. React Router query params become &lt;code&gt;searchParams&lt;/code&gt;. Protected routes need to move into middleware. You'll swap &lt;code&gt;useNavigate()&lt;/code&gt; for &lt;code&gt;useRouter().push()&lt;/code&gt;. And if you're using the App Router, you'll need to rethink how route-based layouts work.&lt;/p&gt;

&lt;p&gt;Getting this mapping done upfront saves you from debugging routing issues a few weeks into moving the existing legacy system to a modern one.&lt;/p&gt;

&lt;h3&gt;
  
  
  Document All External Integrations
&lt;/h3&gt;

&lt;p&gt;Make a list of everything your app talks to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Analytics platforms like GA, PostHog, or Mixpanel&lt;/li&gt;
&lt;li&gt;Authentication providers like Auth0, Firebase, or custom OAuth setups&lt;/li&gt;
&lt;li&gt;Payment gateways like Stripe or PayPal&lt;/li&gt;
&lt;li&gt;CRM tools and marketing pixels&lt;/li&gt;
&lt;li&gt;Headless CMS platforms like Sanity, Strapi, or Contentful&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Tip:&lt;/strong&gt; For each tool, figure out where it'll live in Next.js. Are they server components, API routes, or middleware? It's best done before the migration, so you don't accidentally break something critical halfway through.&lt;/p&gt;

&lt;h3&gt;
  
  
  Evaluate Your Current Data Sources
&lt;/h3&gt;

&lt;p&gt;There are multiple ways to fetch data with Next.js: Server Components with &lt;code&gt;fetch()&lt;/code&gt;, API Route Handlers in &lt;code&gt;app/api/*&lt;/code&gt;, Static Site Generation (SSG), Incremental Static Regeneration (ISR), and Server Actions.&lt;/p&gt;

&lt;p&gt;The questions you should ask yourself are straightforward: Does this data belong in a Server Component or Client Component? Should you fetch it at build time or request time? Can you cache it with ISR for better performance? And can you eliminate client-side fetching?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tip:&lt;/strong&gt; Many apps can eliminate entire &lt;code&gt;useEffect&lt;/code&gt; blocks by moving data fetching to the server.&lt;/p&gt;

&lt;h3&gt;
  
  
  Review the Design
&lt;/h3&gt;

&lt;p&gt;Whether or not you're redesigning, you need to audit what you're working with.&lt;/p&gt;

&lt;p&gt;If you're keeping the current design, go through every page and document all sections, modals, forms, and UI states. You need a complete inventory before you start rebuilding.&lt;/p&gt;

&lt;p&gt;If you're redesigning during migration, review the new designs carefully. Look for gaps, inconsistencies, or missing states. Ask questions now, since it's easier to catch issues in Figma than in code.&lt;/p&gt;

&lt;p&gt;Regardless of your migration strategy, be sure to document these elements:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Buttons and their variants&lt;/li&gt;
&lt;li&gt;Forms and validation states&lt;/li&gt;
&lt;li&gt;Modals and overlays&lt;/li&gt;
&lt;li&gt;Cards and content blocks&lt;/li&gt;
&lt;li&gt;Hero sections, CTAs, and major page sections&lt;/li&gt;
&lt;li&gt;Animations and scroll effects&lt;/li&gt;
&lt;li&gt;Error states (404, 500, loading states)&lt;/li&gt;
&lt;li&gt;Responsive behavior across breakpoints&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Tip:&lt;/strong&gt; Audit your UI components to find what's reusable. Identify common layouts and patterns. While you're at it, check the existing theme configuration to learn which design tokens, colors, and spacing systems are already defined.&lt;/p&gt;

&lt;h3&gt;
  
  
  Audit Layout Variants
&lt;/h3&gt;

&lt;p&gt;Most projects use different layouts for different parts of the site. Map out what you have: global layouts that wrap everything, nested layouts for specific sections, dashboard or admin layouts, marketing page layouts, and authentication layouts.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tip:&lt;/strong&gt; Next.js makes this step easier than most frontends. The App Router lets you define layouts once and reuse them across routes without duplicating code.&lt;/p&gt;

&lt;h3&gt;
  
  
  Optional: Prepare TypeScript Migration
&lt;/h3&gt;

&lt;p&gt;If your old project wasn't in &lt;a href="https://pagepro.co/blog/typescript-vs-javascript/" rel="noopener noreferrer"&gt;TypeScript&lt;/a&gt;, you can add it now. Plan for incremental conversion, so you don't have to type everything on day one. You can set up TS configs in your Next.js project, create shared types for API responses, type your server components, and add types to route handlers as you build them.&lt;/p&gt;

&lt;h3&gt;
  
  
  Choose the Hosting Platform
&lt;/h3&gt;

&lt;p&gt;Your hosting choice determines which performance optimizations you can use, how your caching works, what your deployment pipeline looks like, and what your infrastructure costs will be.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Next.js works best on &lt;strong&gt;Vercel&lt;/strong&gt;. It's built by the same team, so you get zero-config deployment and full support for every Next.js feature out of the box. Edge rendering, Incremental Static Regeneration, image optimization, and middleware all work without extra configuration.&lt;/li&gt;
&lt;li&gt;If you're deploying to &lt;strong&gt;AWS, GCP, or Azure&lt;/strong&gt;, you'll need to handle more setup yourself. You can use containers, serverless functions, or static hosting depending on your infrastructure, but some Next.js features require custom configuration or won't work at all without additional services.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Netlify&lt;/strong&gt; is another solid option with good Next.js support, though it handles certain features differently than Vercel, particularly around ISR and edge functions.&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Hosting Option&lt;/th&gt;
&lt;th&gt;Pros&lt;/th&gt;
&lt;th&gt;Cons&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Vercel&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Native Next.js support, zero-config, edge features&lt;/td&gt;
&lt;td&gt;Higher cost at scale&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;AWS/GCP/Azure&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Flexible, enterprise-ready&lt;/td&gt;
&lt;td&gt;More setup, complex configuration&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Netlify&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Simple workflow, good support&lt;/td&gt;
&lt;td&gt;ISR/edge behaviour differs from Vercel&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Tip:&lt;/strong&gt; Picking the wrong platform can limit the benefits you get from migrating to Next.js in the first place.&lt;/p&gt;

&lt;h2&gt;
  
  
  Migrating Legacy App to Next.js
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Set Up Your Environment
&lt;/h3&gt;

&lt;p&gt;Your migration needs a proper home from day one. Create a new Git repository or branch off your existing one. Create a new Next.js project with &lt;code&gt;create-next-app&lt;/code&gt;, then connect the repo to Vercel or whatever hosting platform you chose. Set up CI/CD pipelines so every change deploys automatically.&lt;/p&gt;

&lt;p&gt;You'll be able to test your migration progress in real time instead of waiting until everything's done to see if it works.&lt;/p&gt;

&lt;h3&gt;
  
  
  Build Reusable Elements First
&lt;/h3&gt;

&lt;p&gt;A solid foundation will save you time and the headache of dealing with messy code. When you build base components and establish patterns upfront, you avoid duplicating code later and give your team clear examples to follow.&lt;/p&gt;

&lt;p&gt;Start with your theme configuration. Set up design tokens (colors, typography, spacing scale, border radii, and breakpoints) early. These become your reference point for styling.&lt;/p&gt;

&lt;p&gt;Then build your base components: buttons, inputs, cards, and other UI elements you'll use everywhere. Set up your typography system and decide on your styling approach, whether that's Tailwind, CSS Modules, or something else.&lt;/p&gt;

&lt;p&gt;Getting this done first means every page you migrate looks consistent, and you won't need to refactor styles halfway through the project.&lt;/p&gt;

&lt;h3&gt;
  
  
  Connect the Data Source
&lt;/h3&gt;

&lt;p&gt;With your base project ready, start connecting to your existing backend or CMS. This is where legacy data starts flowing into the new system.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create API Route Handlers to bridge old and new systems.&lt;/li&gt;
&lt;li&gt;Connect your external APIs and CMS platforms.&lt;/li&gt;
&lt;li&gt;Implement authentication logic, configure server actions if needed, and add caching strategies to improve performance.&lt;/li&gt;
&lt;li&gt;Test the server-side data flow to make sure everything works before you start building UI.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With this done, the rest of your migration project can focus on frontend work. If your legacy systems aren't ready yet, start with mock data and connect real APIs later.&lt;/p&gt;

&lt;h3&gt;
  
  
  Build Global Layouts: Header, Footer, and Shell
&lt;/h3&gt;

&lt;p&gt;With the core setup ready, it's time to wire the application into the systems it relies on. Focus on establishing a reliable backend connection before moving deeper into the migration.&lt;/p&gt;

&lt;p&gt;Break the work into a few clear steps:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Create API route handlers&lt;/strong&gt; to set up endpoints for any server-side logic that needs to live inside the Next.js app.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Integrate external APIs and your CMS&lt;/strong&gt; with internal APIs or third-party platforms.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Implement authentication logic&lt;/strong&gt; to handle sessions, tokens, and permissions in a way that fits your future architecture.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Configure server actions&lt;/strong&gt; and use them for operations that benefit from running securely on the server.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Add caching strategies&lt;/strong&gt; and decide what should be cached, how long, and where.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Test Server-Side Data Flow&lt;/strong&gt; to verify requests, responses, and edge cases so nothing breaks when you start layering in UI components.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A dependable data layer gives the rest of the migration momentum. Once these pieces are in place, your team can build pages without worrying about missing integrations or an unpredictable backend.&lt;/p&gt;

&lt;h3&gt;
  
  
  Move Page Sections One by One
&lt;/h3&gt;

&lt;p&gt;Working in small, contained slices keeps the risk low, makes QA far more manageable, and helps your team surface issues early instead of discovering them at the end. Start shaping the content block by block, then assemble those blocks into complete pages. As you do, connect each part to the right data source and confirm that every state behaves as expected.&lt;/p&gt;

&lt;h3&gt;
  
  
  Add Redirects if Routing Paths Change
&lt;/h3&gt;

&lt;p&gt;Updating systems often involves URL changes. However, they need to be handled carefully to avoid breaking SEO and analytics.&lt;/p&gt;

&lt;p&gt;When the migrated system introduces a new routing structure, set up &lt;code&gt;redirects()&lt;/code&gt; in Next.js to preserve the paths your legacy software relied on. If certain URLs must remain stable, add rewrite rules so old and new systems continue to resolve requests correctly throughout the migration process.&lt;/p&gt;

&lt;p&gt;When everything is mapped, test navigation on both the client and server to confirm that search engines, integrations, and users all reach the right destinations.&lt;/p&gt;

&lt;h3&gt;
  
  
  Optional: Implement Monitoring
&lt;/h3&gt;

&lt;p&gt;Even the best migration plan won't catch every issue. Setting up monitoring in place gives you a safety net throughout the migration process and once the new system is live.&lt;/p&gt;

&lt;p&gt;Tools like Sentry or LogRocket surface problems like client and server errors, slow API endpoints, route performance drops, hydration mismatches, or unexpected regressions early. Your team can react before they turn into user-facing outages.&lt;/p&gt;

&lt;h3&gt;
  
  
  Ensure SEO Requirements Are Met
&lt;/h3&gt;

&lt;p&gt;SEO can be harmed during data migration, so treat it as a core part of the modernization project.&lt;/p&gt;

&lt;p&gt;Review every page to confirm titles, descriptions, OpenGraph fields, canonical tags, and previous SEO rules carry over correctly. It's also worth scanning the new layout for structural issues like duplicated H1 tags or missing alt text, which can affect rankings.&lt;/p&gt;

&lt;p&gt;Next.js helps you protect (and often improve) organic visibility with features such as the Metadata API, dynamic OpenGraph fields, server-rendered HTML, route-level sitemaps, &lt;code&gt;robots.txt&lt;/code&gt;, and built-in image optimization. Decide early how metadata will be generated and where custom logic is needed, especially if you're moving away from legacy systems with hardcoded SEO fields or CMS-driven templates.&lt;/p&gt;

&lt;h4&gt;
  
  
  Metadata Example
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;metadata&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Your Page Title&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Your description.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;openGraph&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;images&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/og-image.jpg&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Test Performance Early and Often
&lt;/h3&gt;

&lt;p&gt;Keep an eye on performance while moving from your current system. Run Lighthouse and PageSpeed Insights regularly to confirm caching works as expected, Core Web Vitals stay on track, images are sized correctly, and your ISR/SSR logic behaves predictably. It will also let you spot any hydration issues early, long before they turn into bigger problems.&lt;/p&gt;

&lt;p&gt;Next.js comes with many performance advantages, but those optimizations only pay off if they're configured correctly. Keeping a close eye on performance as you modernize the system helps prevent regressions, protects the gains you're aiming for, and saves your team time as the migrated system grows.&lt;/p&gt;

&lt;h3&gt;
  
  
  Add Testing &amp;amp; QA Before Launch
&lt;/h3&gt;

&lt;p&gt;Before you wrap up the migration project, make room for a proper testing pass. It doesn't need to slow the team down, but skipping it almost always shows up later as production bugs, SEO drops, or unpredictable behaviour in the migrated system.&lt;/p&gt;

&lt;p&gt;A solid QA layer usually includes a mix of unit tests (Jest or Vitest), end-to-end checks (Playwright or Cypress), accessibility scans, visual regression tests, and even simple dead-link audits. Together, these help catch layout issues, broken states, missing metadata, and any quirks introduced while moving legacy components into a modern architecture.&lt;/p&gt;

&lt;p&gt;Treat this stage as the final safety net before the new system goes live. It's a chance to confirm you just conducted a successful migration.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final Post-Migration Checklist
&lt;/h2&gt;

&lt;p&gt;Use this checklist to make sure nothing slips through the cracks before your new platform goes live:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;[ ] Routes and redirects verified&lt;/li&gt;
&lt;li&gt;[ ] SEO data (titles, descriptions, OG tags, canonicals) carried over&lt;/li&gt;
&lt;li&gt;[ ] Analytics and tracking reconnected&lt;/li&gt;
&lt;li&gt;[ ] All UI states and edge cases tested&lt;/li&gt;
&lt;li&gt;[ ] Performance benchmarks (Lighthouse, CWV) meet targets&lt;/li&gt;
&lt;li&gt;[ ] Accessibility checks passed&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Successful Legacy System Migration to Next.js
&lt;/h2&gt;

&lt;p&gt;By the time you reach this point, most of the heavy lifting is done. You've modernized the structure, tightened up performance, protected SEO, and brought the legacy system to Next.js.&lt;/p&gt;

&lt;p&gt;What's left is simply making sure the new environment behaves the way your team and users expect it to. A thoughtful rollout, a final round of QA, and clear internal communication will help the migrated system settle in smoothly. From here, your team can stop wrestling with older systems and start building faster, cleaner, and with far fewer surprises.&lt;/p&gt;

&lt;p&gt;If you're looking at moving away from a legacy setup and want support from a team that's done this many times, reach out to us! Pagepro can help you plan and execute a smooth transition to Next.js and see what the best path forward looks like.&lt;/p&gt;

&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;What is an Example of a Legacy System?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A legacy system is older software or infrastructure that still runs critical operations but was built on outdated technology. Common examples include on-premise ERPs, custom CMS platforms, monolithic applications, COBOL-based banking systems, and websites running on outdated frameworks or databases. These systems often work reliably but limit modern development, integration, and scaling efforts.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why are Legacy Systems Still Used Today?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Legacy systems stay in place because they run essential workflows, and replacing them can feel risky, costly, or disruptive. Many teams keep using them because the system is deeply embedded in daily operations, staff already know how it works, and the business relies on custom logic built over many years. The challenge is that staying on older systems slows innovation, increases security risks, and makes scaling harder.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What are the Disadvantages of Legacy Systems?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Legacy systems create ongoing problems as they age. They're expensive to maintain, hard to integrate with modern tools, and more vulnerable to security issues. Performance tends to drop over time, updates require more effort, and teams lose agility because old technology can't support new workflows, cloud services, or modern user experience standards. As technical debt grows, so do the risks of outages and compliance failures.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Is Replacing a Legacy System Worth It?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Replacing a legacy system is worth considering when the cost, risk, and operational drag outweigh the stability it provides. Modern platforms offer better performance, stronger security, lower maintenance costs, and more flexibility for future features. If a legacy system slows development, blocks integrations, harms SEO, or creates reliability issues, migrating to a modern architecture usually delivers a clear long-term return.&lt;/p&gt;

</description>
      <category>architecture</category>
      <category>javascript</category>
      <category>nextjs</category>
      <category>react</category>
    </item>
    <item>
      <title>How to Replatform Your Website Without Trouble?</title>
      <dc:creator>Mariusz</dc:creator>
      <pubDate>Thu, 09 Jul 2026 16:00:59 +0000</pubDate>
      <link>https://dev.to/maniekm/how-to-replatform-your-website-without-trouble-cce</link>
      <guid>https://dev.to/maniekm/how-to-replatform-your-website-without-trouble-cce</guid>
      <description>&lt;h2&gt;
  
  
  Is a Website Replatform Necessary?
&lt;/h2&gt;

&lt;p&gt;Slow load times can seriously impact your sites or online store’s digital presence. Even hardcore digital marketers and SEO specialists will not be able to do much if your current website performs poorly, and a clunky site will turn away potential clients and affect your revenue. Perhaps it’s time to replatform your website.&lt;/p&gt;

&lt;p&gt;If the user experience of your website is sub-par, the top of Google search results will remain out of reach. To get there, you’re going to need proper technical support to back up your content.&lt;/p&gt;

&lt;p&gt;The goal of this article is to help you understand the process of migration better so that you can communicate your needs to developers more efficiently. We’re going to go over some symptoms which may indicate whether you need to start the replatforming project of your website. &lt;/p&gt;

&lt;h2&gt;
  
  
  What is Replatforming
&lt;/h2&gt;

&lt;p&gt;Replatforming is migrating your data to a different CMS. There could be hundreds of reasons to migrate your data to a different platform. However, the most prevailing reasons are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Slow website&lt;/li&gt;
&lt;li&gt;Limited scalability&lt;/li&gt;
&lt;li&gt;Bad customer experience&lt;/li&gt;
&lt;li&gt;High maintenance costs&lt;/li&gt;
&lt;li&gt;Limited integration features of your current CMS&lt;/li&gt;
&lt;li&gt;Security issues&lt;/li&gt;
&lt;li&gt;SEO in need of improvement&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Replatforming can be a very cost-efficient investment. Kiwi Storage wanted to migrate from their WordPress website due to several limitations, including restricted functionality, reliance on external developers, and security concerns. Their migration allowed for better content management and integration of custom features. Not to mention a superb site performance!&lt;/p&gt;

&lt;p&gt;A smartphone and a tablet display a storage company website built with a bespoke UI component library, showing the text Self Storage in London - We Collect, Store &amp;amp; Deliver next to an illustration of a green van and two people loading boxes.&lt;br&gt;
And, as technology keeps moving forward, the businesses that are unaware of the new software solutions are simply falling behind.&lt;/p&gt;

&lt;h2&gt;
  
  
  Choosing a New CMS for Replatforming
&lt;/h2&gt;

&lt;p&gt;When deciding to replatform, it’s essential to understand the differences between a traditional CMS and a headless CMS.&lt;/p&gt;

&lt;h3&gt;
  
  
  Headless CMS
&lt;/h3&gt;

&lt;p&gt;A headless CMS, such as Contentful or Sanity, decouples the content management from the presentation layer. The content is stored and managed separately from how it’s displayed, allowing it to be delivered to multiple platforms through APIs.&lt;/p&gt;

&lt;p&gt;Many businesses are shifting to headless CMSs for their performance benefits and the ability to create seamless omnichannel experiences. A headless setup can future-proof your website, allowing you to integrate new technologies more easily, but requires technical expertise to set up and maintain.&lt;/p&gt;

&lt;p&gt;Migration to a headless CMS is a very common occurrence among businesses. &lt;/p&gt;

&lt;p&gt;Lyngen North migrated to a headless CMS from WordPress to improve management and flexibility, addressing WordPress’s limitations in functionality and integrations. They needed a fast, high-performance site for high-resolution visuals without compromising speed. The switch to Sanity enhanced scalability, content control, and SEO optimization.&lt;/p&gt;

&lt;p&gt;A website to replatform your glass igloo and house rentals is displayed on a tablet and smartphone, showing a night scene with northern lights above a glass igloo. The navigation menu and booking options are visible.&lt;br&gt;
If you find out more about headless CMS, be sure to read our articles on the advantages of the headless approach and the 5 best headless CMS available on the market.&lt;/p&gt;

&lt;h3&gt;
  
  
  Traditional CMS
&lt;/h3&gt;

&lt;p&gt;Platforms like WordPress and Drupal are traditional CMSs. They combine both the content management and presentation layers in one system, meaning the backend (where you create content) and the frontend (how the content is displayed) are tightly integrated. &lt;/p&gt;

&lt;p&gt;While this approach can be easier to set up and manage, it can limit flexibility, especially when delivering content across multiple platforms like mobile apps, websites, and other channels.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to Migrate Your Current Platform
&lt;/h2&gt;

&lt;p&gt;Step-by-step vs all-at-once methods head to head.&lt;br&gt;
There are two most prominent ways of replatforming a website. One is taking the time and migrating the data all at once. The other is migrating the data step by step.&lt;/p&gt;

&lt;h2&gt;
  
  
  Deciding to Replatform All at Once
&lt;/h2&gt;

&lt;p&gt;Replatforming everything at once works well if you have clear documentation and a well-defined migration plan. Not everyone can afford a brief downtime for testing and deploying the site, but if you can or the old system is becoming too costly or cumbersome to maintain, migrating everything at the same time is a great choice. &lt;/p&gt;

&lt;h3&gt;
  
  
  Pros:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;All your data is transferred at once&lt;/li&gt;
&lt;li&gt;Unified user experience&lt;/li&gt;
&lt;li&gt;Easier testing and debugging&lt;/li&gt;
&lt;li&gt;Simpler project management&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Cons:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;It can be time-consuming&lt;/li&gt;
&lt;li&gt;Your old website with all its issues will have to remain in use until the update&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Switch Your Website to a New Platform Step-By-Step&lt;br&gt;
Instead of replatforming and re-constructing everything at once, you can release the new version of your website step-by-step. To do that, your devs are going to be re-writing HTTP and directing traffic through path-based routing.&lt;/p&gt;

&lt;p&gt;Step-by-step migration approach is best when your site is large, needs to stay operational at all times, or you have budget constraints. It’s also helpful if your team has limited capacity, as they can work in manageable phases instead of handling everything. &lt;/p&gt;

&lt;h3&gt;
  
  
  Pros:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;You can deliver parts of the new website quicker&lt;/li&gt;
&lt;li&gt;Add new features step-by-step&lt;/li&gt;
&lt;li&gt;Replace problematic systems and infrastructure sooner&lt;/li&gt;
&lt;li&gt;Deliver new functionalities for a better user experience&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Cons:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Requires complex methods of integrating new modules with the old system while transferring data&lt;/li&gt;
&lt;li&gt;Successful Replatforming Can Be Complicated&lt;/li&gt;
&lt;li&gt;The best approach to replatforming depends on your specific situation.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you have the time and want to introduce your new platform with a big launch, replatforming everything at once could make sense. But if you’re aiming to improve the customer experience as soon as possible, the incremental step-by-step method might be the better choice.&lt;/p&gt;

&lt;p&gt;Keep in mind that whether you choose the step-by-step or the all-at-once method for migration without proper preparation, you’re still going to be running in the dark. It’s important to have the process figured out before you start to avoid additional costs. &lt;/p&gt;

&lt;p&gt;If you do not have a clear-cut path to reinventing your website, you should consider hiring professionals to help you. In the long run, you’ll save yourself a lot of nerves and money. &lt;/p&gt;

&lt;h3&gt;
  
  
  Keep the Layout Consistent
&lt;/h3&gt;

&lt;p&gt;First of all, the page content, the header, and the footer all have to be consistent throughout your pages. When replatforming your website, chances are you’re looking to create and launch an entirely new website. More often than not, this means switching to a new content management system and doing so while continuing to work on the old one can confuse you and your users.&lt;/p&gt;

&lt;p&gt;To keep both the old and the new sites consistent consider either updating the old version with the new design or copying the design of the old version and applying it to the new one until the project is finished.&lt;/p&gt;

&lt;p&gt;Don’t forget details like error pages and favicons. These might seem irrelevant, but they’re necessary to keep your website consistent.&lt;/p&gt;

&lt;h3&gt;
  
  
  Provide a Single Shared Session for the Entire Site
&lt;/h3&gt;

&lt;p&gt;If you have a marketing background, you already the customer journey should remain as smooth as possible. To achieve this, we must apply a single shared session for the entire platform.&lt;/p&gt;

&lt;p&gt;It’s no secret people generally find accepting cookies annoying, so it’s better to avoid forcing them to do this again each time your website switches from the old version to the new one.&lt;/p&gt;

&lt;p&gt;More importantly in the case of eCommerce sites, you don’t want your customers to lose their carts when, for example, moving from the cart section to the transaction section. This small issue could end up costing a lot of money and customer loyalty.&lt;/p&gt;

&lt;h3&gt;
  
  
  Check Third-Party Scripts and Tags
&lt;/h3&gt;

&lt;p&gt;Regardless if you’re using WordPress, Sanity, or any other content management system, you’re no stranger to 3rd party tools integration. &lt;/p&gt;

&lt;p&gt;Oftentimes analytics tools for ad tracking and site verification like Google Pixel are installed in both the  and  parts of your websites.&lt;/p&gt;

&lt;p&gt;To keep things consistent, be sure these get either transferred or replaced so your site can keep collecting the necessary data. You don’t want to lose your analytics tools during the replatforming process!&lt;/p&gt;

&lt;h3&gt;
  
  
  Include the New Site’s Pages in the Sitemap
&lt;/h3&gt;

&lt;p&gt;A sitemap is an .XML file that holds information about different elements like pages, images, videos, and all the other files on your website. It also includes important information about all of the relationships between them.&lt;/p&gt;

&lt;p&gt;To ensure the proper functionality of your new site, your developers have to remember to include all the pages from the new site in the sitemap. Create an index file with sitemaps from both the new and the old versions of your website.&lt;/p&gt;

&lt;h2&gt;
  
  
  Do I Need to Migrate My Website?
&lt;/h2&gt;

&lt;p&gt;The crucial part is to recognize whether your website’s performance issues aren’t slowing your business down or impacting search engine optimization. Then, once you’ve recognized the problem, it may be time to make an educated choice of deciding to go all out and migrate all of the data at once or do so through the step-by-step method. You might want to reach out for professional help in new system integration or even a website audit to optimize the migration process.&lt;/p&gt;

&lt;p&gt;While you might be tempted to invest in paid ads and promotions, these will not bring you the benefits you’re looking for if your website is not up to the task. Replatforming and maintenance costs will be nothing compared to what you are bound to lose in the long run if your existing website lacks in performance and doesn’t suit your business needs.&lt;/p&gt;

</description>
      <category>performance</category>
      <category>seo</category>
      <category>ux</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Why is Gatsby JS Good for Google Rankings?</title>
      <dc:creator>Mariusz</dc:creator>
      <pubDate>Fri, 18 Sep 2020 12:34:10 +0000</pubDate>
      <link>https://dev.to/pagepro_agency/why-is-gatsby-js-good-for-google-rankings-2g6</link>
      <guid>https://dev.to/pagepro_agency/why-is-gatsby-js-good-for-google-rankings-2g6</guid>
      <description>&lt;p&gt;SEO, which stands for Search Engine Optimisation), doesn't seem to get old — it's just different every year. Google changes its Search Algorithm and Ranking System every once in a while, adding new ranking factors or modifying existing ones. And since 2018, the page speed is one of them.&lt;/p&gt;

&lt;p&gt;However, there are more: content relevancy, mobile-friendliness, user experience, on-page optimisation... There are more than 200 of them in total. It's mind-blowing, isn't it?&lt;/p&gt;

&lt;p&gt;However, you don't have to take them all into account — focus on the most important ones.&lt;/p&gt;

&lt;p&gt;And if you are wondering how to do that and create a website with the highest chances to rank high, consider Gatsby.&amp;nbsp;&lt;/p&gt;

&lt;p&gt;Keep reading to check why!&lt;/p&gt;

&lt;h2&gt;&lt;strong&gt;What is SEO?&lt;/strong&gt;&lt;/h2&gt;

&lt;p&gt;Search Engine Optimisation (SEO) is a set of practices aimed to make a particular website look better and better in the eyes of Google. In other words, SEO is about improving the quality and quantity of website's traffic coming through search engine results pages (SERPs).&lt;/p&gt;

&lt;p&gt;Search engine result page, on the other hand, is a page that displays mainly (but not only) results returned by a search engine like Google as a response to query search such as "online shopping" or "front-end development agency".&lt;/p&gt;

&lt;h2&gt;&lt;strong&gt;Why does SEO matter?&lt;/strong&gt;&lt;/h2&gt;

&lt;p&gt;SEO helps companies bring valuable, organic traffic to their websites which is the first step towards getting new clients and increasing revenue. The better SEO-optimised the site is, the higher it's ranked in SERPs. And the higher the ranking is, the bigger the traffic.&lt;/p&gt;

&lt;p&gt;The main difference between organic traffic (brought by SEO) and paid traffic (brought by money) is that the first one is free, forever. However, great SEO has more benefits than just saving money:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;It drives the quality traffic to your website&lt;/strong&gt;&amp;nbsp;— instead of reaching out to people whether they want to or not (interruption marketing), SEO focuses on making it easy for them to find you when they want to (permission marketing).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Organic results get more clicks than paid ads&lt;/strong&gt; — it's hard to tell why that is, but it doesn't alter the statistics: &lt;a href="https://www.advancedwebranking.com/blog/google-organic-ctr/#ctr-study" rel="noreferrer noopener nofollow"&gt;over 70% of searches&lt;/a&gt; end in clicking an organic result on the first page.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;SEO supports Public Relations efforts&lt;/strong&gt;&amp;nbsp;— one of the main elements of SEO is link building, which is about earning links from industry-respected publications and other relevant websites. On the other hand, featuring in such publications and being mentioned by influencers is a primary point of PR strategy. This presents an excellent opportunity to get in front of new customers through, for example, guest posting.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;It helps you to overtake the competition&lt;/strong&gt; — SEO is an essential part of most marketing strategies which means there is a huge chance that your competition is already fighting for better rankings. However, with well-prepared and well-executed SEO efforts, you can catch up with them or even surpass them.&lt;/p&gt;

&lt;h2&gt;&lt;strong&gt;Main SEO ranking factors&lt;/strong&gt;&lt;/h2&gt;

&lt;p&gt;There is a legend circulating in the marketing world that there is a man who knows all SEO ranking factors used by Google. However, no one ever saw him.&lt;/p&gt;

&lt;p&gt;Luckily, you don't have to know them all – only the main ones. But since giving specific SEO advice is not our goal here, we will just scratch the surface to provide you with an overview.&lt;/p&gt;

&lt;h3&gt;&lt;strong&gt;Accessibility&lt;/strong&gt;&lt;/h3&gt;

&lt;p&gt;All your efforts to rank high will be for nothing if your website is not visible to search engine crawlers. These are robots that are crawling through the Internet to index websites. If the specific site is not indexed correctly, it won't be displayed in search results.&lt;/p&gt;

&lt;p&gt;What you have to do is create robots.txt file and website's sitemap. It's a confirmation of your site's accessibility. However, you can go one step further by submitting your website to Google through Google Search Console.&lt;/p&gt;

&lt;h3&gt;&lt;strong&gt;Backlinks&lt;/strong&gt;&lt;/h3&gt;

&lt;p&gt;This is one of the most crucial SEO ranking factors, if not the most crucial one. As a reminder, backlinks are links to one website inserted on another website. The more backlinks you earn, the better it is for your website's SEO.&lt;/p&gt;

&lt;p&gt;However, it's more complicated than it looks like. Every single backlink and its effect on SEO is influenced by other factors like relevancy or domain authority.&lt;/p&gt;

&lt;h3&gt;&lt;strong&gt;Mobile-friendliness&lt;/strong&gt;&lt;/h3&gt;

&lt;p&gt;Mobile-friendliness (or responsiveness) is a ranking factor for both mobile and desktop searches. If your website fully adapts to a visitor's device — whether it's a small-screen mobile phone or big-screen TV — it means that it's mobile-friendly (or responsive). And this is very much welcomed by Google.&lt;/p&gt;

&lt;p&gt;You can check if your website is mobile-friendly with &lt;a href="https://search.google.com/test/mobile-friendly" rel="noreferrer noopener nofollow"&gt;Google's official tool&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;&lt;strong&gt;On-page optimisation&lt;/strong&gt;&lt;/h3&gt;

&lt;p&gt;All efforts within the website that are intended to improve the website's position in search engine results are called on-page optimisation. Among them are: creating proper title and meta tags, using the right keywords, optimising images, writing original and valuable content.&lt;/p&gt;

&lt;h3&gt;&lt;strong&gt;Page speed (desktop and mobile)&lt;/strong&gt;&lt;/h3&gt;

&lt;p&gt;Page speed has been a ranking factor for a decade now. And two years ago it started to affect not only desktop searches but also mobile searches. However, don't treat it like a challenge to beat competitors by trying to make your website load a few milliseconds faster. Instead, make it fast enough, so it won't affect the user experience negatively.&lt;/p&gt;

&lt;p&gt;One more thing: according to Google's research, one-third of visitors will leave your website if page load time goes from one to three seconds. If it takes longer, it's even worse.&lt;/p&gt;

&lt;h3&gt;&lt;strong&gt;User experience&lt;/strong&gt;&lt;/h3&gt;

&lt;p&gt;Would you come back to a place where you have had a terrible experience? Doubtful. The same thing goes for websites — the first impression makes all the difference. If the user experience is awful, it's likely you won't revisit it.&lt;/p&gt;

&lt;p&gt;While it's not clear how exactly Google measures user's satisfaction from visiting a particular website, they gave some suggestions about what's essential from the UX perspective:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Content that's useful and easy to read&lt;/li&gt;
&lt;li&gt;Design that's responsive and responds to users' needs&lt;/li&gt;
&lt;li&gt;Well-organised site architecture&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;&lt;strong&gt;Dynamic site vs static site: which one is better for SEO?&lt;/strong&gt;&lt;/h2&gt;

&lt;p&gt;There is one more thing to consider: what kind of website should you choose to raise your chances of ranking high in search engine results pages. First of all, there are two main website types — dynamic site and static site.&lt;/p&gt;

&lt;h3&gt;&lt;strong&gt;What is a dynamic site?&lt;/strong&gt;&lt;/h3&gt;

&lt;p&gt;Dynamic sites allow users to interact with the content posted on a website. That content is being generated in real-time, which means it can be different for different users, depending on their location, device, time zone, or even network.&lt;/p&gt;

&lt;p&gt;A dynamic website can use client-side scripting (the browser executes code), server-side scripting (the server runs code) or a combination of both.&lt;/p&gt;

&lt;p&gt;A good example of such websites are those built using a Content Management System (CMS) like WordPress or Drupal.&amp;nbsp;&lt;/p&gt;

&lt;h3&gt;&lt;strong&gt;What is a static site?&lt;/strong&gt;&lt;/h3&gt;

&lt;p&gt;Static websites, on the contrary, offer the same content for every visitor, regardless of their browser's language or other preferences. For every page, there is a specific HTML file on the server that contains the content of this page. Such a website is pre-rendered and is not meant to be regularly updated because it requires some HTML knowledge to edit source files.&lt;/p&gt;

&lt;p&gt;A good example of such websites is simple business websites created using static site generators (SSG) like Gatsby.&lt;/p&gt;

&lt;h3&gt;&lt;strong&gt;Which one does Google prefer?&lt;/strong&gt;&lt;/h3&gt;

&lt;p&gt;While both types serve different purposes and require different skills, let's take a look at dynamic sites and static sites from Google perspective.&lt;/p&gt;

&lt;h4&gt;&lt;strong&gt;Static sites are faster.&lt;/strong&gt;&lt;/h4&gt;

&lt;p&gt;Page load speed is one of the leading SEO ranking factors, which also affects user experience in either a good or bad way. Static sites are faster than dynamic sites because they are pre-rendered. Pre-rendering means that your website is generated as a set of static files in advance, not in real-time.&amp;nbsp;&lt;/p&gt;

&lt;h4&gt;&lt;strong&gt;Static sites are easier to index.&lt;/strong&gt;&lt;/h4&gt;

&lt;p&gt;Static websites consist of HTML and CSS files which are extremely easy to read and index by Google crawlers. Another thing that helps with indexation is a simple sitemap which is recommended by all search engines, including Google.&lt;/p&gt;

&lt;h4&gt;
&lt;strong&gt;Static sites are easier to optimise&lt;/strong&gt;.&lt;/h4&gt;

&lt;p&gt;When you decide to choose a static site, you gain total control over SEO. You can customise any page of your website in any way you want. In a case of dynamic websites, you need to install a plugin or two to help you with SEO efforts.&lt;/p&gt;

&lt;h4&gt;
&lt;strong&gt;Static sites are less expensive to host and maintain&lt;/strong&gt;.&lt;/h4&gt;

&lt;p&gt;Since static sites consist of simple HTML files, they need much less space on the hosting server than dynamic sites. Also, such a website won't use much of the monthly transfer limit.&lt;/p&gt;

&lt;h2&gt;&lt;strong&gt;What is Gatsby?&lt;/strong&gt;&lt;/h2&gt;

&lt;p&gt;If you are considering creating a static site, Gatsby may be your choice of tool to do so. It is a free and open-source framework created with React, helping developers to build blazingly fast sites and apps. Gatsby is also called static site generator (SSG).&lt;/p&gt;

&lt;h2&gt;&lt;strong&gt;Why is Gatsby good for SEO?&lt;/strong&gt;&lt;/h2&gt;

&lt;p&gt;It's time for the most important part of this article. I haven't jumped straight to that from the beginning because I wanted to explain the context. So far, you found out:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;what is SEO&lt;/li&gt;
&lt;li&gt;what does it matter&lt;/li&gt;
&lt;li&gt;main SEO ranking factors&lt;/li&gt;
&lt;li&gt;which one is better for SEO: dynamic site or static site&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It helped you to understand the whole picture better, right?&lt;/p&gt;

&lt;p&gt;Now it's time to find out why Gatsby is good for SEO.&lt;/p&gt;

&lt;h3&gt;&lt;strong&gt;Accessibility&lt;/strong&gt;&lt;/h3&gt;

&lt;p&gt;Web accessibility means that websites, tools and technologies should be designed to be accessible for everyone, especially for those with permanent or temporary disabilities. When it comes to Gatsby and its accessibility, WebAIM (Web Accessibility in Mind, non-profit organisation) recognised Gatsby as the most accessible web framework.&lt;/p&gt;

&lt;p&gt;Gatsby uses different practices to make its websites as much accessible as possible:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Accessible routing&lt;/strong&gt; — the main feature of every website is navigation, and accessible routing takes care of that. Thanks to it, you can, for example, use a keyboard to navigate through the website. Also, Gatsby manages page announcements on page change.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Building HTML pages by default&lt;/strong&gt; — since it's using Node.js environment to compile pages, you don't have to worry about progressive page enhancement. Progressive enhancement means that the core page content is loaded before anything else from the server.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Linting using a plugin&lt;/strong&gt; — Gatsby uses&amp;nbsp;an &lt;em&gt;eslint-plugin-jsx-a11y&lt;/em&gt; package that reduces the time needed to find accessibility errors. This plugin, among other things, encourages you to add alternative text to all images.&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;&lt;strong&gt;Page metadata&lt;/strong&gt;&lt;/h3&gt;

&lt;p&gt;Gatsby gives you full control over the website's content and structure, and consequently, over the SEO of this website. You can add metadata like page titles, meta descriptions and alt text, which helps search engines to understand the content on your website and when to display your site in search results.&lt;/p&gt;

&lt;p&gt;To add metadata to your website, you can use react-helmet components. Remember to add Gatsby React Helmet plugin to support SSR (server-side rendering).&lt;/p&gt;

&lt;h3&gt;&lt;strong&gt;Performance and speed&lt;/strong&gt;&lt;/h3&gt;

&lt;p&gt;Gatsby is all about performance and speed. It comes with built-in features like rendering to static files or progressive image loading which are responsible for making Gatsby website fast. According to 2018 Google's update, site speed became the new ranking factor, and faster websites will likely rank higher than the slower ones.&amp;nbsp;&lt;/p&gt;

&lt;p&gt;However, you should still create content that's valuable and relevant to visitors, because the slower but more relevant site may rank higher than the faster ones.&lt;/p&gt;

&lt;h3&gt;&lt;strong&gt;Structured data&lt;/strong&gt;&lt;/h3&gt;

&lt;p&gt;Structured data is what Google looks for on the web to understand the website's content. This is also its source of general information about the web and the world.&lt;/p&gt;

&lt;p&gt;The better Google understands the content, the more relevant search results are. In other words, if you use structured data on your website, it helps you to rank higher.&lt;/p&gt;

&lt;p&gt;In Gatsby, you can add structured data snippets with react-helmet in the JSON-LD (JavaScript Object Notation for Linked Data) format, which is embedded either in the page head or page body.&lt;/p&gt;

&lt;h3&gt;&lt;strong&gt;User experience&lt;/strong&gt;&lt;/h3&gt;

&lt;p&gt;All the points made above ensure great user experience to visitors. And it's not just about the site speed — with Gatsby you can create fully customised websites that are accessible to everyone, easy to find and navigate, and visually attractive.&lt;/p&gt;

&lt;h2&gt;&lt;strong&gt;Examples of Websites built with Gatsby&lt;/strong&gt;&lt;/h2&gt;

&lt;p&gt;Many well-known companies decided to build their websites using Gatsby — Airbnb, Bitcoin.com, Braun, Spotify, to name a few. However, there is no limitation on who can use Gatsby because startups and small companies also choose it.&lt;/p&gt;

&lt;p&gt;Check below examples to see how such websites look and perform:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://airbnb.io/" rel="noreferrer noopener nofollow"&gt;Airbnb Engineering &amp;amp; Data Science&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://bitcoin.com" rel="noreferrer noopener nofollow"&gt;Bitcoin.com&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://ca.braun.com/en-ca" rel="noreferrer noopener nofollow"&gt;Braun&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://frame.io" rel="noreferrer noopener nofollow"&gt;Frame.io&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://hopper.com" rel="noreferrer noopener nofollow"&gt;Hopper&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://spotify.design" rel="noreferrer noopener nofollow"&gt;Spotify.design&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://frontend-day.com" rel="noreferrer noopener"&gt;Frontend Day conference&lt;/a&gt; created by Pagepro&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://jsminds.com" rel="noreferrer noopener"&gt;JS Minds&lt;/a&gt; created by Pagepro&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Many well-known companies decided to build their websites with Gatsby — like Braun, Spotify and AirBnb, just to name a few.&lt;/p&gt;

&lt;h2&gt;&lt;strong&gt;Alternatives to Gatsby&lt;/strong&gt;&lt;/h2&gt;

&lt;p&gt;We highly recommend Gatsby to build static sites, but we also would like to help you make a fully informed decision. Because of that, we wrote about Gatsby alternatives — you can read about them &lt;a href="https://pagepro.co/blog/is-gatsbyjs-the-best-framework-for-building-static-websites-what-are-the-other-alternatives/" rel="noreferrer noopener"&gt;here&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>gatsby</category>
      <category>react</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Is React Native Good for Startups?</title>
      <dc:creator>Mariusz</dc:creator>
      <pubDate>Thu, 03 Sep 2020 13:37:45 +0000</pubDate>
      <link>https://dev.to/pagepro_agency/is-react-native-good-for-startups-23i9</link>
      <guid>https://dev.to/pagepro_agency/is-react-native-good-for-startups-23i9</guid>
      <description>&lt;p&gt;Building a startup is like driving a sports-car. It's fun, it's exciting, but it is also about fast yet wise decisions. Making mistakes is not an option, and the danger is high. You may either crash your car or run out of gas before getting to your planned destination.&lt;/p&gt;

&lt;p&gt;If you want to avoid this, choose your vehicle and engine that comes with it wisely. And reading this piece will help you to decide whether choosing React Native for startups is actually a good idea.&lt;/p&gt;

&lt;h2&gt;&lt;strong&gt;What is React Native?&lt;/strong&gt;&lt;/h2&gt;

&lt;p&gt;React Native is an open-source, cross-platform framework created by Facebook in 2015 for building mobile applications using React. It's like an engine for your startup's app. It allows developers to accelerate the development of native apps for operating systems like Android and iOS.&lt;/p&gt;

&lt;p&gt;React, in turn, is a JavaScript library, which was created to build user interfaces.&lt;/p&gt;

&lt;p&gt;If you want to become more familiar with React Native, read our &lt;a href="https://pagepro.co/blog/what-is-react-native-a-definite-guide-to-the-top-mobile-framework/" rel="noreferrer noopener"&gt;comprehensive guide&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;&lt;strong&gt;Which startups use React Native?&lt;/strong&gt;&lt;/h2&gt;

&lt;p&gt;React Native is a choice for many companies, from tech giants like Facebook itself to young startups looking for funding. If you are curious, here is the list of some popular applications that have been built using this trend-setting technology:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Discord&lt;/li&gt;
&lt;li&gt;Facebook&lt;/li&gt;
&lt;li&gt;Facebook Analytics&lt;/li&gt;
&lt;li&gt;Instagram&lt;/li&gt;
&lt;li&gt;Pinterest&lt;/li&gt;
&lt;li&gt;Skype&lt;/li&gt;
&lt;li&gt;Salesforce&lt;/li&gt;
&lt;li&gt;Uber Eats&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--KjDZ-ON3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://lh3.googleusercontent.com/DKO2TaEORMONff01zHzbQqpETwH6N15Zx6jpiyr-jSR3kZp6xbh5QBpQ_gOeWyCQYGZRuua3f_uEVTattmRyQ_Y8V1XtNC8g4OhRjP6TrJprr5vScR95j6FaJXN6LyMakex97R-g" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--KjDZ-ON3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://lh3.googleusercontent.com/DKO2TaEORMONff01zHzbQqpETwH6N15Zx6jpiyr-jSR3kZp6xbh5QBpQ_gOeWyCQYGZRuua3f_uEVTattmRyQ_Y8V1XtNC8g4OhRjP6TrJprr5vScR95j6FaJXN6LyMakex97R-g" alt="Popular brands using React Native"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There are more examples, but it all comes down to this: if they rely on React Native, why shouldn't the others?&lt;/p&gt;

&lt;p&gt;And that’s just the way startups that use React Native like &lt;a href="https://mattermost.com/" rel="noreferrer noopener nofollow"&gt;Mattermost&lt;/a&gt; (self-hosted open-source Slack alternative) or &lt;a href="https://www.ovalmoney.com/" rel="noreferrer noopener nofollow"&gt;Oval&lt;/a&gt; (creators of personal finance app) think.&lt;/p&gt;

&lt;h2&gt;&lt;strong&gt;When to consider choosing React Native?&lt;/strong&gt;&lt;/h2&gt;

&lt;p&gt;Choosing the proper technology for your mobile application is challenging. But it may become a bit easier after reflecting on needs, estimated budget and available time. Therefore, there are some scenarios in which React Native might be the right choice. Consider choosing React Native:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;If you have native apps&lt;/strong&gt; &lt;strong&gt;already&lt;/strong&gt;— if you already have iOS and/or Android applications, you can change to React Native, because it doesn't require re-writing the entire code which makes migration a lot easier (check &lt;a href="https://blog.khanacademy.org/our-transition-to-react-native/"&gt;here&lt;/a&gt; how Khan Academy managed such a transition)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;To scale quickly&lt;/strong&gt; — it's easy to hire or train React Native developers so growing a team fast is not a problem.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;To create MVP fast&lt;/strong&gt; — having just an idea is not enough, and you must test it in real market conditions. In other words, you need to create an MVP as fast as possible.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;If you have tight deadlines&lt;/strong&gt; — if you work in a startup, you need to move fast. Need-for-Speed-like fast or even faster. And it's not about creating MVP. It's also about making constant changes and updates with as little effort and time as it's needed.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;If your budget is strictly limited&lt;/strong&gt; — having just an idea is not enough for most investors. A minimum you need is working MVP, but there is a chance that you won't finish it before running out of money. Using React Native will help you minimise that risk.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
&lt;strong&gt;Benefits of using React Native&lt;/strong&gt; for Startups&lt;/h2&gt;

&lt;p&gt;Looking closely at benefits is always a good idea when it comes to making more or less important decisions. To help you make a great one regarding technology for your startup, we prepared a list of benefits from both business and technical perspectives.&lt;/p&gt;

&lt;h3&gt;&lt;strong&gt;Benefits from a business perspective&lt;/strong&gt;&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Excellent User Experience&lt;/strong&gt; — User Experience of any digital product is essential to its success. While technically a React Native app is not "the app", it looks and feels like it. Especially because it's fully responsive.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Stability and evolvement&lt;/strong&gt; — since its foundation, React Native matured, is still evolving and backed up by a huge community. Most common problems are already solved. Therefore, the risk of using it doesn't exist.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Developers availability&lt;/strong&gt; — React Native is not a new technology or one that nobody knows. The reverse is true: the developer marketplace is robust. You can either hire freelancers using websites like Upwork or &lt;a href="https://pagepro.co/contact.html" rel="noreferrer noopener"&gt;talk to an agency like ours&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Shortened time to market (TTM)&lt;/strong&gt; — the sky is the limit, and time is the money. As a startup, you don't want to create an app for months without showing it to real users and future customers. React Native boosts up mobile development up to 50% in comparison to native app development so startups can create working MVP even twice as fast.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Money savings&lt;/strong&gt; — this point is highly connected with the previous points. Still, there is more: a decision to build a single cross-platform app is far better economical choice than creating two separate applications for iOS and Android.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Time savings&lt;/strong&gt; — using React Native means that you don't have to create two separate applications for two separate platforms. Not to mention the time you will spend on upgrading and fixing them.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;&lt;strong&gt;Benefits from a technical perspective&lt;/strong&gt;&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Compatibility with back-end technologies&lt;/strong&gt; — you can use React Native with back-end frameworks like Django or Ruby on Rails, and it will work like a charm&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Declarative style&lt;/strong&gt; — it's about &lt;strong&gt;WHAT&amp;nbsp;&lt;/strong&gt;you want to do, in a contrary to imperative style, which is about&amp;nbsp;&lt;strong&gt;HOW&lt;/strong&gt; you want to do it. For example, let's say that you hired a private chef and want to eat a fancy dinner at home. Instead of telling him&amp;nbsp;&lt;strong&gt;HOW&amp;nbsp;&lt;/strong&gt;to do it (imperative style), you just say&amp;nbsp;&lt;strong&gt;WHAT &lt;/strong&gt;you want (declarative style), i.e. "Make me Hawaii pizza, please."&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dynamic development&lt;/strong&gt; — since its creation in 2015, React Native evolved both as a technology and community, and it doesn't seem it will rest on its's laurels. Because of that, you can be sure of two things: (1) it's more future-proof than some other technologies and (2) the chances of finding someone to hire or to help you are very high.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hot Reloading&lt;/strong&gt; — in short, it allows you for making changes to your app code while it's still up and running. It accelerates app developments significantly because your app can reload automatically.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Open-source community&lt;/strong&gt; — if you are stuck somewhere along the development process, you can always go to GitHub or Reddit to ask for help, and there is a great chance that someone will help you out&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reusable components&lt;/strong&gt; — why write the same code again and again, when you can re-use already-built elements? It works across both iOS and Android, and it's enough to update a particular component in one view. It's possible because updates will be automatically made in each case of using this component&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Third-party extensions support&lt;/strong&gt; — React Native is all about speeding up the development process. Apart from RN itself, you can use many third-party plugins and frameworks like &lt;a href="https://nativebase.io/"&gt;NativeBase&lt;/a&gt; (which helps you to create native-like apps) or &lt;a href="https://galio.io/"&gt;Galio&lt;/a&gt;&amp;nbsp;(which is a library of UI components)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;&lt;strong&gt;Disadvantages of using React Native&lt;/strong&gt;&lt;/h2&gt;

&lt;p&gt;Unfortunately, it's not all rainbows and butterflies. Like any other technology, React Native also has its flaws:&amp;nbsp;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Complicated updating process&lt;/strong&gt; — keeping your cross-platform application always up with the latest React Native version is a challenge. It's a complicated process that's much easier in the case of native apps.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Issues with more complicated design&lt;/strong&gt; — React Native may not be the best choice if you want to use gain business leverage by using some advanced interactions or custom graphics&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Lack of custom modules&lt;/strong&gt; — sometimes, you will have to build specific components from scratch.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Messy code after migration&lt;/strong&gt; — you may have to rewrite some code to make necessary adjustments or to make APIs work correctly again.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;&lt;strong&gt;When to choose a native app instead of React Native?&lt;/strong&gt;&lt;/h2&gt;

&lt;p&gt;It’s not like that cross-platform app is always a better choice than going with a native app. There are some scenarios in which it's better to choose the latter option. Consider native app if:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Performance is what you care most about&lt;/li&gt;
&lt;li&gt;Security is your priority, i.e. if you are in the FinTech industry.&lt;/li&gt;
&lt;li&gt;Your app will be heavy on graphics. In other words, if you want to include advanced interactions, custom animations, or various screen transitions in your app.&lt;/li&gt;
&lt;li&gt;Your app will require a lot of interactions with hardware like GPS, i.e. if it uses geolocation tracking.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;&lt;strong&gt;Alternatives to React Native&lt;/strong&gt;&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--vS2G80jb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://lh3.googleusercontent.com/lt4YdSlG-keIQ6taiikaTP1aZZ-dub9E_cqEqosvLBikPNhdIemFnnU0wWgXNurw9DRCLwnRlVqE1Xk8vOjQvo53fjKCCYXYK5iV91uTOUn8T8k9HU8kD6GmgtnargaTC7fi6m5W" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vS2G80jb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://lh3.googleusercontent.com/lt4YdSlG-keIQ6taiikaTP1aZZ-dub9E_cqEqosvLBikPNhdIemFnnU0wWgXNurw9DRCLwnRlVqE1Xk8vOjQvo53fjKCCYXYK5iV91uTOUn8T8k9HU8kD6GmgtnargaTC7fi6m5W" alt="React Native alternatives"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Flutter&lt;/strong&gt; — it's a framework created by Google to build mobile, web, and desktop applications using a single codebase. To find out more, read our &lt;a href="https://pagepro.co/blog/react-native-vs-flutter-which-is-better-for-cross-platform-app/" rel="noreferrer noopener"&gt;comparison between these two&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Xamarin&amp;nbsp;&lt;/strong&gt;— it’s a framework created by Microsoft, which allows developers to build iOS and Android applications. But in a contrary to React Native, Xamarin apps are written in C#.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ionic&amp;nbsp;&lt;/strong&gt;— thanks to it, developers can use standard web technologies like Javascript, HTML and CSS to build cross-platform mobile applications. The difference between React Native and Ionic is that Ionic is hybrid, and the RN is native.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All of the above alternatives are cross-platform and open-source solutions.&lt;/p&gt;

&lt;h2&gt;React Native &lt;strong&gt;FAQ&lt;/strong&gt;
&lt;/h2&gt;

&lt;h3&gt;&lt;strong&gt;How long does it take to build a React Native application?&lt;/strong&gt;&lt;/h3&gt;

&lt;p&gt;The reply is: it depends (it’s our favourite answer). While choosing React Native to build an application speeds up the development process up to 50% in comparison to native app development, the time needed depends on the complexity of the desired application.&lt;/p&gt;

&lt;p&gt;Such an estimation can be prepared after outlining the software complexity by both sides.&lt;/p&gt;

&lt;h3&gt;&lt;strong&gt;How much does it cost?&lt;/strong&gt;&lt;/h3&gt;

&lt;p&gt;Again, it depends. Development agency can give you a ballpark estimate of your project, including time and money needed, after outlining its complexity.&lt;/p&gt;

&lt;h2&gt;What's next?&lt;/h2&gt;

&lt;p&gt;If you are more like a reader, you can check our &lt;a href="https://pagepro.co/blog/what-is-react-native-a-definite-guide-to-the-top-mobile-framework/" rel="noreferrer noopener"&gt;comprehensive guide on React Native&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>react</category>
      <category>reactnative</category>
      <category>webdev</category>
      <category>startup</category>
    </item>
    <item>
      <title>Using Next.js as a Static Site Generator</title>
      <dc:creator>Mariusz</dc:creator>
      <pubDate>Fri, 21 Aug 2020 09:55:10 +0000</pubDate>
      <link>https://dev.to/pagepro_agency/using-next-js-as-a-static-site-generator-3bo1</link>
      <guid>https://dev.to/pagepro_agency/using-next-js-as-a-static-site-generator-3bo1</guid>
      <description>&lt;p&gt;Static Site Generators are becoming extremely popular in the world of &lt;a rel="noreferrer noopener" href="https://pagepro.co/web-app-development.html"&gt;web development&lt;/a&gt; and Next.js is a proud competitor in this race. &lt;/p&gt;

&lt;h2&gt;&lt;b&gt;What are Static Site Generators?&lt;/b&gt;&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;🚀 STATIC = BLAZINGLY FAST 🚀&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Static Site Generator are extremely fast. Once loaded, they prefetches resources for other pages so clicking around the site feels like a blonk of an eye.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;💎 STATIC = SAFE 💎&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You will just publish static files, which means there is no direct connection to the database, dependencies, user data or other sensitive information.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;😎 STATIC = ENHANCED USER EXPERIENCE 😎&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Simply because clicking and walking through your website feels like a walk in a park on a sunny day with no unexpected turns, stairs, or dead ends. &lt;/p&gt;

&lt;h2&gt;&lt;b&gt;What is Next.js?&lt;/b&gt;&lt;/h2&gt;

&lt;p&gt;“Next is a framework which we can use to build React sites with Server Side Rendering or generate static pages from our react code. All that configured for us by Next itself.”&lt;/p&gt;

&lt;p&gt;And in this post we will be taking a look at the static pages export functionality and how we can make it with next.js.&lt;/p&gt;

&lt;p&gt;Let's go! &lt;/p&gt;

&lt;h2&gt;&lt;b&gt;Creating an app&lt;/b&gt;&lt;/h2&gt;

&lt;p&gt;We will start by creating a new next app. To do that simply run the command:&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="n"&gt;yarn&lt;/span&gt; &lt;span class="n"&gt;create&lt;/span&gt; &lt;span class="n"&gt;next&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;app&lt;/span&gt;
&lt;span class="c1"&gt;# or if you are using npm&lt;/span&gt;
&lt;span class="n"&gt;npx&lt;/span&gt; &lt;span class="n"&gt;create&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;next&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;app&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, let’s take a look at our project structure:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fpagepro.co%2Fblog%2Fwp-content%2Fuploads%2F2020%2F07%2Fstructre.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fpagepro.co%2Fblog%2Fwp-content%2Fuploads%2F2020%2F07%2Fstructre.png" alt="next app structure"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;b&gt;&lt;em&gt;pages&lt;/em&gt;&lt;/b&gt; - this directory contains all our pages and defines routing for our app (&lt;a rel="noreferrer noopener nofollow" href="https://nextjs.org/docs/routing/introduction"&gt;more about routing here&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;&lt;b&gt;&lt;em&gt;pages/api&lt;/em&gt;&lt;/b&gt; - here we can add our API endpoint if we need some, in our case we can remove this folder safely (&lt;a rel="noreferrer noopener nofollow" href="https://nextjs.org/docs/api-routes/introduction"&gt;more about API routes here&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;&lt;b&gt;&lt;em&gt;public&lt;/em&gt;&lt;/b&gt; - we can put all our static assets in this directory.&lt;/p&gt;

&lt;p&gt;Let’s change our commands to reflect what we want to achieve in this project. Got to package.json and modify scripts section like this:&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;dev&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;next dev&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="err"&gt;#&lt;/span&gt; &lt;span class="nx"&gt;remove&lt;/span&gt;
&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;build&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;next build&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;build&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;next build &amp;amp;&amp;amp; next export&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;start&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;next start&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;start&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;next dev&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So now our scripts section should look like this:&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="p"&gt;...&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;scripts&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;build&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;next build &amp;amp;&amp;amp; next export&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;start&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;next dev&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we can test our configuration, run the build command:&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="n"&gt;yarn&lt;/span&gt; &lt;span class="n"&gt;run&lt;/span&gt; &lt;span class="n"&gt;build&lt;/span&gt;
&lt;span class="c1"&gt;# or if you are using npm&lt;/span&gt;
&lt;span class="n"&gt;npm&lt;/span&gt; &lt;span class="n"&gt;run&lt;/span&gt; &lt;span class="n"&gt;build&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next should create &lt;strong&gt;out&lt;/strong&gt; directory at the root of our project with all the static html files and assets ready to host. We can change the &lt;strong&gt;out&lt;/strong&gt; directory by adding a &lt;strong&gt;-o &lt;/strong&gt;flag to our &lt;strong&gt;next export&lt;/strong&gt; command like this:&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="p"&gt;...&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;scripts&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;build&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;next build &amp;amp;&amp;amp; next export -o build&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;...&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;&lt;b&gt;Adding content to page&lt;/b&gt;&lt;/h2&gt;

&lt;p&gt;Let’s head to &lt;strong&gt;pages\index.js&lt;/strong&gt; file and remove the content of &lt;strong&gt;Home&lt;/strong&gt; component and change it like this:&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Home&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nx"&gt;Hello&lt;/span&gt; &lt;span class="nx"&gt;From&lt;/span&gt; &lt;span class="nx"&gt;my&lt;/span&gt; &lt;span class="nx"&gt;next&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;js&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/p&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;Home&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And start our app by running command:&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="n"&gt;yarn&lt;/span&gt; &lt;span class="n"&gt;run&lt;/span&gt; &lt;span class="n"&gt;build&lt;/span&gt;
&lt;span class="c1"&gt;# or if you are using npm&lt;/span&gt;
&lt;span class="n"&gt;npm&lt;/span&gt; &lt;span class="n"&gt;run&lt;/span&gt; &lt;span class="n"&gt;build&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now you should be able to access http://localhost:3000 and see our Home component content.&lt;/p&gt;

&lt;p&gt;Now let’s add some content that will be evaluated at the build time. We can do that by using &lt;strong&gt;getStaticProps&lt;/strong&gt; which is a function exported from our page. As we don’t have any data source configured yet we will do a simple example to show how &lt;strong&gt;getStaticProps&lt;/strong&gt; work.&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Home&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;buildTimestamp&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nx"&gt;Hello&lt;/span&gt; &lt;span class="nx"&gt;From&lt;/span&gt; &lt;span class="nx"&gt;my&lt;/span&gt; &lt;span class="nx"&gt;next&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;js&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;
      &lt;span class="nx"&gt;App&lt;/span&gt; &lt;span class="nx"&gt;built&lt;/span&gt; &lt;span class="na"&gt;at&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;buildTimestamp&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/p&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;getStaticProps&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;props&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;buildTimestamp&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;Home&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We will see that &lt;strong&gt;buildTimestamp&lt;/strong&gt; changes every refresh, this will not be the case when we build our app because &lt;strong&gt;getStaticProps&lt;/strong&gt; is called only once when app is building.&lt;/p&gt;

&lt;h2&gt;&lt;b&gt;Adding data source&lt;/b&gt;&lt;/h2&gt;

&lt;p&gt;We already know how &lt;strong&gt;getStaticProps&lt;/strong&gt; works, now we can make it more useful and add some external data source to our app. Next.js doesn’t come with any data provider built in (for example GatsbyJS has graphql) so we will have to add it manually. &lt;/p&gt;

&lt;p&gt;Basically you can load your data however you like. In this tutorial we will use GraphQL with Apollo Client. First let’s add src directory where we will keep all our code shared between pages. Then create &lt;strong&gt;src\setup\apolloClient.js&lt;/strong&gt; file where our apollo client will be created.&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;ApolloClient&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;apollo-client&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;HttpLink&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;apollo-link-http&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;InMemoryCache&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;apollo-cache-inmemory&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;apolloClient&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ApolloClient&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;link&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;HttpLink&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;uri&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://gitlab.com/api/graphql&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;}),&lt;/span&gt;
  &lt;span class="na"&gt;cache&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;InMemoryCache&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;apolloClient&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Additionally we will have to install some apollo realated packages. Simply run the command:&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="n"&gt;yarn&lt;/span&gt; &lt;span class="n"&gt;run&lt;/span&gt; &lt;span class="n"&gt;add&lt;/span&gt; &lt;span class="n"&gt;apollo&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;cache&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;inmemory&lt;/span&gt; &lt;span class="n"&gt;apollo&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="n"&gt;apollo&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;link&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;http&lt;/span&gt; &lt;span class="n"&gt;graphql&lt;/span&gt; &lt;span class="n"&gt;graphql&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;tag&lt;/span&gt;
&lt;span class="c1"&gt;# or if you are using npm&lt;/span&gt;
&lt;span class="n"&gt;npm&lt;/span&gt; &lt;span class="n"&gt;install&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;save&lt;/span&gt; &lt;span class="n"&gt;apollo&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;cache&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;inmemory&lt;/span&gt; &lt;span class="n"&gt;apollo&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="n"&gt;apollo&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;link&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;http&lt;/span&gt; &lt;span class="n"&gt;graphql&lt;/span&gt; &lt;span class="n"&gt;graphql&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;tag&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see we will be using GitLab graphql api (&lt;a rel="noreferrer noopener nofollow" href="https://gitlab.com/-/graphql-explorer"&gt;explorer is available here&lt;/a&gt;).&lt;/p&gt;

&lt;h2&gt;&lt;b&gt;Creating pages and fetching data&lt;/b&gt;&lt;/h2&gt;

&lt;p&gt;Now we can fetch some data, let’s fetch some repositories. First we have to create graphql query:&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;PROJECTS_QUERY&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;gql&lt;/span&gt;&lt;span class="s2"&gt;`
  query {
    projects (first: 10) {
      nodes {
        id
        name
        description
      }
    }
  }
`&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we can import apollo client and use it with above query in our &lt;strong&gt;getStaticProps&lt;/strong&gt;:&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;getStaticProps&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;apolloClient&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;query&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;query&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;PROJECTS_QUERY&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;props&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;projects&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;projects&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now list of GitLab projects is available in our &lt;strong&gt;Home&lt;/strong&gt; component props, let’s render it.&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Home&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;projects&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;ul&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;projects&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;nodes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(({&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;description&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;li&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;strong&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/strong&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;description&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;span&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;description&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/span&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;}
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/li&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="p"&gt;))}&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/ul&amp;gt;&lt;/span&gt;&lt;span class="err"&gt; 
&lt;/span&gt;  &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And that’s it, we have a working GitLab projects list. &lt;/p&gt;

&lt;p&gt;Now let’s add project detail page. &lt;/p&gt;

&lt;p&gt;First we have to add dynamic route to our app, we can do that by creating a file with square brackets in its name, like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fpagepro.co%2Fblog%2Fwp-content%2Fuploads%2F2020%2F07%2Fsquare.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fpagepro.co%2Fblog%2Fwp-content%2Fuploads%2F2020%2F07%2Fsquare.png" alt="a square presenting how to save a project with square brackets"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a rel="noreferrer noopener nofollow" href="https://nextjs.org/docs/routing/dynamic-routes"&gt;More about dynamic routing here.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When we are building our pages statically Next.js requires us to export a function called &lt;strong&gt;getStaticPaths&lt;/strong&gt; from our page. &lt;/p&gt;

&lt;p&gt;We have to do that because Next.js needs to know all the page urls and their params at the build time. We have fetched first 10 Gitlab projects at our homepage so now we have to do the same in our &lt;strong&gt;getStaticPaths&lt;/strong&gt; to generate urls.&lt;/p&gt;

&lt;p&gt;First let’s add links to projects details on homepage. We have to add fullPath field to our query:&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;PROJECTS_QUERY&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;gql&lt;/span&gt;&lt;span class="s2"&gt;`
  query {
    projects (first: 10) {
      nodes {
        id
        name
        description
        fullPath
      }
    }
  }
`&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And render next link for every project:&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Home&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;projects&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;ul&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;projects&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;nodes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(({&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;description&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;fullPath&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;li&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;strong&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/strong&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;description&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;span&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;description&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/span&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;}
&lt;/span&gt;          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Link&lt;/span&gt;
              &lt;span class="nx"&gt;href&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/project/[...fullPath]&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
              &lt;span class="k"&gt;as&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;`/project/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;fullPath&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
              &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Details&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/a&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Link&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/li&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="p"&gt;))}&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/ul&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we can add code to our project details page:&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;gql&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;graphql-tag&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;apolloClient&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;../../src/setup/apolloClient&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ProjectDetailsPage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;fullPath&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Project&lt;/span&gt; &lt;span class="nx"&gt;details&lt;/span&gt; &lt;span class="nx"&gt;page&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;fullPath&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;ProjectDetailsPage&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;PROJECTS_QUERY&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;gql&lt;/span&gt;&lt;span class="s2"&gt;`
  query {
    projects(first: 10) {
      nodes {
        fullPath
      }
    }
  }
`&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;getStaticPaths&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;apolloClient&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;query&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;query&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;PROJECTS_QUERY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;paths&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;projects&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;nodes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(({&lt;/span&gt; &lt;span class="nx"&gt;fullPath&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="c1"&gt;// 1&lt;/span&gt;
      &lt;span class="na"&gt;params&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;fullPath&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;fullPath&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;})),&lt;/span&gt;
    &lt;span class="na"&gt;fallback&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// 2&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;getStaticProps&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;params&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;props&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;fullPath&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fullPath&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// 3&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let’s explain some key parts here:&lt;/p&gt;

&lt;ol&gt;&lt;li&gt;We map our projects list to an array of paths required by Next.js. Structure that Nexts.js expects looks like this:&lt;/li&gt;&lt;/ol&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;paths&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
       &lt;span class="na"&gt;params&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
         &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;all&lt;/span&gt; &lt;span class="nx"&gt;params&lt;/span&gt; &lt;span class="nx"&gt;that&lt;/span&gt; &lt;span class="nx"&gt;we&lt;/span&gt; &lt;span class="nx"&gt;want&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt; &lt;span class="nx"&gt;pass&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt; &lt;span class="nx"&gt;getStaticProps&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
       &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Also when we use Catch All route we have to pass our param as array that’s why we use split here.&lt;/p&gt;

&lt;ol start="2"&gt;
&lt;li&gt;We have to tell next if we want to render missing pages live or just return 404. In our case we are making fully static page so we define fallback as false. &lt;a href="https://nextjs.org/docs/basic-features/data-fetching#the-fallback-key-required" rel="noreferrer noopener nofollow"&gt;More about fallback here&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt; We merge our fullPath param to single string so we can display it nicely in our component.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Now we can change &lt;strong&gt;getStaticProps&lt;/strong&gt; to be more useful and fetch some project data for us. First we need query for project details:&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;PROJECT_DETAILS_QUERY&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;gql&lt;/span&gt;&lt;span class="s2"&gt;`
  query ($fullPath: ID!) {
    project(fullPath: $fullPath) {
      name
      descriptionHtml
      repository {
        empty
        tree {
          lastCommit {
            sha
          }
        }
      }
    }
  }
`&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And run it inside of our &lt;strong&gt;getStaticProps&lt;/strong&gt;&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;getStaticProps&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;params&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;fullPath&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fullPath&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;apolloClient&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;query&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;query&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;PROJECT_DETAILS_QUERY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;variables&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;fullPath&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;props&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;project&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;project&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we can display some data on our project details page:&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ProjectDetailsPage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;project&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;descriptionHtml&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;repository&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;tree&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;project&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;lastCommit&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;tree&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;sha&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;lastCommit&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;

  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;h1&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/h1&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt; &lt;span class="nx"&gt;dangerouslySetInnerHTML&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt; &lt;span class="na"&gt;__html&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;descriptionHtml&lt;/span&gt; &lt;span class="p"&gt;}}&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;sha&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Last&lt;/span&gt; &lt;span class="nx"&gt;commit&lt;/span&gt; &lt;span class="na"&gt;SHA&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;sha&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/p&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;}
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And that’s it, we have created a static page displaying first 10 GitLab projects and their details. &lt;/p&gt;

&lt;p&gt;We can now build it and serve to check if everything is working properly.&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="n"&gt;yarn&lt;/span&gt; &lt;span class="n"&gt;run&lt;/span&gt; &lt;span class="n"&gt;build&lt;/span&gt;
&lt;span class="c1"&gt;# or if you are using npm&lt;/span&gt;
&lt;span class="n"&gt;npm&lt;/span&gt; &lt;span class="n"&gt;run&lt;/span&gt; &lt;span class="n"&gt;build&lt;/span&gt;

&lt;span class="c1"&gt;# if you are using yarn and don't have serve installed run this command first&lt;/span&gt;
&lt;span class="n"&gt;yarn&lt;/span&gt; &lt;span class="k"&gt;global&lt;/span&gt; &lt;span class="n"&gt;add&lt;/span&gt; &lt;span class="n"&gt;serve&lt;/span&gt;


&lt;span class="c1"&gt;# if you are using yarn&lt;/span&gt;
&lt;span class="n"&gt;serve&lt;/span&gt; &lt;span class="mf"&gt;.&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;build&lt;/span&gt;
&lt;span class="c1"&gt;# or if you are using npm&lt;/span&gt;
&lt;span class="n"&gt;npx&lt;/span&gt; &lt;span class="n"&gt;serve&lt;/span&gt; &lt;span class="mf"&gt;.&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;build&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a rel="noreferrer noopener" href="https://github.com/Pagepro/nextjs-static-site-generator"&gt;Access the full project here. &lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;&lt;b&gt;Next.js vs GatsbyJS&lt;/b&gt;&lt;/h2&gt;

&lt;p&gt;As we can see &lt;strong&gt;Next.js&lt;/strong&gt; can successfully generate static pages like &lt;strong&gt;GatsbyJS&lt;/strong&gt; does and someone could ask:&lt;/p&gt;

&lt;p&gt;“Can Next.js replace GatsbyJS?”&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fpagepro.co%2Fblog%2Fwp-content%2Fuploads%2F2020%2F07%2Fyes-and-no.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fpagepro.co%2Fblog%2Fwp-content%2Fuploads%2F2020%2F07%2Fyes-and-no.png" alt="a cartoon pirate is saying you cannot actually replace GatsbyJS with Next.JS"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can do all the things in Next.js that you do in GatsbyJS but it take much more time because you need to do everything by yourself. &lt;/p&gt;

&lt;p&gt;GatsbyJS has a lot of plugins that help to solve many problems and optimize the page. More than that it has data fetching features built in (graphql available out of the box). So for now we will have to wait for Next.js ecosystem to grow and get more plugins so we can create static pages as fast as we do in GatsbyJS.&lt;/p&gt;

&lt;p&gt;Keep in mind that &lt;strong&gt;Next.js has one big advantage over GatsbyJS&lt;/strong&gt;: &lt;/p&gt;

&lt;ul&gt;&lt;li&gt;you can create and app which is partially static and dynamic. &lt;/li&gt;&lt;/ul&gt;

&lt;p&gt;For example you can prerender first 10 posts from your blog and the rest can be rendered when the page is requested by user.&lt;/p&gt;

&lt;p&gt;So for now Next.js is just a more flexible solution that requires more work and gives us some powerful extra features but in terms of development time GatsbyJS is still better.&lt;/p&gt;

</description>
      <category>react</category>
      <category>webdev</category>
      <category>javascript</category>
      <category>todayilearned</category>
    </item>
    <item>
      <title>React Native Code Review - A Checklist
</title>
      <dc:creator>Mariusz</dc:creator>
      <pubDate>Tue, 04 Aug 2020 13:34:47 +0000</pubDate>
      <link>https://dev.to/pagepro_agency/checklist-for-a-successful-react-native-code-review-4742</link>
      <guid>https://dev.to/pagepro_agency/checklist-for-a-successful-react-native-code-review-4742</guid>
      <description>&lt;p&gt;Did you ever want to do a code review of &lt;a href="https://pagepro.co/react-native-development.html"&gt;React Native app&lt;/a&gt; by yourself? &lt;/p&gt;

&lt;p&gt;If yes, let me guide you through the whole process, step-by-step with our own checklist.&lt;/p&gt;

&lt;p&gt;But if you are quite new to the subject of code review, let's start from the basics.&lt;/p&gt;

&lt;h2&gt;&lt;b&gt;What is Code Review?&lt;/b&gt;&lt;/h2&gt;

&lt;p&gt;Code review is a form of deep and profound analysis of the existing codebase. It comes with a set of specific activities and checklist points that leads you step-by-step through the process of identifying and uncovering current and potential bugs and problems.&lt;/p&gt;

&lt;h2&gt;&lt;b&gt;When Should I Do a React Native Code Review?&lt;/b&gt;&lt;/h2&gt;

&lt;p&gt;Different &lt;a href="https://pagepro.co/" rel="noreferrer noopener"&gt;React Native Developers&lt;/a&gt; face different scenarios, but it doesn't matter if:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;you just took over an app from a different developer, or&lt;/li&gt;
&lt;li&gt;someone asked you to improve the existing app, or&lt;/li&gt;
&lt;li&gt;you just built an app and want to make sure it’s flawless…&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;…you need to have a deep understanding of what’s inside and where the potential source of errors may be hidden.&lt;/p&gt;

&lt;p&gt;And if you think about it, there may be many areas that code review will appear to be highly recommended, if not absolutely necessary. &lt;/p&gt;

&lt;h3&gt;&lt;b&gt;Improve Performance&lt;/b&gt;&lt;/h3&gt;

&lt;p&gt;First of all, code review is extremely important if it comes to app performance.&lt;/p&gt;

&lt;p&gt;While talking about React Native and the cross-platform applications in general, their performance and user-interface is considered sometimes as the biggest challenge.&lt;/p&gt;

&lt;p&gt;The goal is to make the final experience native-like. Which means performance has to be outstanding.&lt;/p&gt;

&lt;p&gt;And this is when the code review is a great idea, as it is able to uncover many flaws and areas of improvement.&lt;/p&gt;

&lt;h3&gt;&lt;b&gt;Scale Easier&lt;/b&gt;&lt;/h3&gt;

&lt;p&gt;Planning your future app improvement demands a deep understanding of its architecture.&lt;/p&gt;

&lt;p&gt;The analysis of a fundamental app functionalities will help you plan how actually you can improve it later on.&lt;/p&gt;

&lt;h3&gt;&lt;b&gt;After Changes and Improvements&lt;/b&gt;&lt;/h3&gt;

&lt;p&gt;As you know it’s almost impossible to build and release an app without few changes here and there. &lt;a href="https://reactnative.dev/" rel="noreferrer noopener nofollow"&gt;React Native&lt;/a&gt; apps are no different.&lt;/p&gt;

&lt;p&gt;Keeping a code review checklist on your sight makes it easier to keep your app in shape despite the changes you have made.&lt;/p&gt;

&lt;h3&gt;&lt;b&gt;React Native Bug Fixing&lt;/b&gt;&lt;/h3&gt;

&lt;p&gt;Even if you went through and passed many different tests, it doesn’t really mean your app is totally ready to hit the market.&lt;/p&gt;

&lt;p&gt;Unfortunately many bugs are becoming visible only after a bit heavier usage by the final users.&lt;/p&gt;

&lt;p&gt;Deep analysis of your code is able to spot them, before they arrive.&lt;/p&gt;

&lt;h3&gt;&lt;b&gt;Detect Platform-based Functionalities&lt;/b&gt;&lt;/h3&gt;

&lt;p&gt;While building React Native applications, you will probably have things working on one platform (f.e. iOS), but not working on the other (Android).&lt;/p&gt;

&lt;p&gt;Code audit helps you detect those “platform-based” features and functionalities, and fix them at an early stage.&lt;/p&gt;

&lt;h3&gt;&lt;b&gt;Before Final Release&lt;/b&gt;&lt;/h3&gt;

&lt;p&gt;React Native code review is also a great way (and quite obvious) for a “final checkup”.&lt;/p&gt;

&lt;p&gt;Before the release you may want to check if all works fine, and if the code is following the latest development standards.&lt;/p&gt;

&lt;h2&gt;&lt;b&gt;Reasons Summary&lt;/b&gt;&lt;/h2&gt;

&lt;p&gt;To sum it up, React Native code review may be helpful to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Find areas of improvement for your app performance&lt;/li&gt;
&lt;li&gt;Get a deep understanding of the app architecture to scale it easier&lt;/li&gt;
&lt;li&gt;Identify and uncover existing and potential bugs and problems&lt;/li&gt;
&lt;li&gt;Identify “platform-based” functionalities&lt;/li&gt;
&lt;li&gt;Keep your app in shape despite constant changes&lt;/li&gt;
&lt;li&gt;Prepare your app to be released with no flaws&lt;/li&gt;
&lt;li&gt;Making sure your app is following the latest development standards&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;&lt;b&gt;How To Do a React Native Code Review?&lt;/b&gt;&lt;/h2&gt;

&lt;p&gt;If you want to do your code review well, I suggest to start going with the following order:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;span class="has-inline-color has-vivid-red-color"&gt;Primary audit&lt;/span&gt;&lt;/strong&gt; - in this stage you go through the app structure and the fundamental functionalities.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;span class="has-inline-color has-vivid-red-color"&gt;Automatic analysis&lt;/span&gt;&lt;/strong&gt; - in this stage you push the code through the most popular automatic test engines to uncover the most frequent issues and common violations.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;span class="has-inline-color has-vivid-red-color"&gt;In-depth analysis&lt;/span&gt;&lt;/strong&gt; - this is the manual part, where you extensively go through our list to uncover bugs, performance issues, potential future problems, security vulnerabilities, etc.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;&lt;b&gt;React Native Code Review Checklist&lt;/b&gt;&lt;/h2&gt;

&lt;p&gt;Enough theory.&lt;/p&gt;

&lt;p&gt;Let’s get to work. Here’s your React Native app Health Checklist, step-by-step:&lt;/p&gt;

&lt;h3&gt;&lt;b&gt;1. Versions&lt;/b&gt;&lt;/h3&gt;

&lt;p&gt;First, check if:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;React Native version is up to date.&lt;/li&gt;
&lt;li&gt;All dependencies are up to date.&lt;/li&gt;
&lt;li&gt;Dependencies (that use RN linking) are not deprecated and supporting latest RN version.&lt;/li&gt;
&lt;li&gt;Dependencies in package.json are meeting the industry standards.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;&lt;b&gt;2. Development&lt;/b&gt;&lt;/h3&gt;

&lt;p&gt;Then, check if:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;App is ejected/use Expo.&lt;/li&gt;
&lt;li&gt;App got own native modules written (no support from npm).&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;&lt;b&gt;3. Code Quality:&lt;/b&gt;&lt;/h3&gt;

&lt;p&gt;After that, check if:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Tests are written.&lt;/li&gt;
&lt;li&gt;There is a typing solution implemented (TypeScript / Prop Types / Flow).&lt;/li&gt;
&lt;li&gt;Code follow best practices.&lt;/li&gt;
&lt;li&gt;Eslint and/or prettier is added.&lt;/li&gt;
&lt;li&gt;Codebase has consistent code style.&lt;/li&gt;
&lt;li&gt;Code is easy to understand (self describing) so we can make changes without trying to understand logic for a week.&lt;/li&gt;
&lt;li&gt;Check imports through files (unused imports).&lt;/li&gt;
&lt;li&gt;Check most common usage native files and code quality in it (MainApplication etc).&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;&lt;b&gt;4. Test Run&lt;/b&gt;&lt;/h3&gt;

&lt;p&gt;Finally, check if:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Development tasks are running.&lt;/li&gt;
&lt;li&gt;Build is working for any platform (Android, iOS).&lt;/li&gt;
&lt;li&gt;There are no problems with putting apps in stores.&lt;/li&gt;
&lt;li&gt;There are any CI/CD processes implemented.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;&lt;b&gt;Summary&lt;/b&gt;&lt;/h2&gt;

&lt;p&gt;React Native Code Review may appear an important step in your app development process.&lt;/p&gt;

&lt;p&gt;It helps you understand the app taken over from another developer, helps you uncover the potential problems and bugs, and finally, makes your app ready for the market.&lt;/p&gt;

&lt;p&gt;If you do it well, you can save yourself tons of work, and will make your app working well for a long time.&lt;/p&gt;

</description>
      <category>reactnative</category>
      <category>webdev</category>
      <category>codequality</category>
      <category>mobileapp</category>
    </item>
    <item>
      <title>2020 Report: React in a Business Perspective - Key Takeaways</title>
      <dc:creator>Mariusz</dc:creator>
      <pubDate>Thu, 25 Jun 2020 10:50:18 +0000</pubDate>
      <link>https://dev.to/pagepro_agency/2020-report-react-in-a-business-perspective-key-takeaways-48l7</link>
      <guid>https://dev.to/pagepro_agency/2020-report-react-in-a-business-perspective-key-takeaways-48l7</guid>
      <description>&lt;p&gt;Many years ago, we chose &lt;a href="https://reactjs.org/" rel="noreferrer noopener nofollow"&gt;React.js&lt;/a&gt; and &lt;a href="https://reactnative.dev/" rel="noreferrer noopener nofollow"&gt;React Native&lt;/a&gt; as the core of our technology stack.&lt;/p&gt;

&lt;p&gt;The longer we were working with it, the more we were satisfied with our choice, and we quickly gathered a team of &lt;a href="https://pagepro.co/" rel="noreferrer noopener"&gt;React developers&lt;/a&gt; totally dedicated to this library.&lt;/p&gt;

&lt;p&gt;However, we started investigating if this love wasn’t just a quick affair.&lt;/p&gt;

&lt;p&gt;A “halo effect”, or the BS talk we’ve been selling ourselves to help us believe we do the right thing, just because we are already doing it.&lt;/p&gt;

&lt;p&gt;So, we took the laptop, and we’ve interviewed CTOs and Dev Team Leaders to check if choosing React and React Native somehow impacted their everyday work, and ultimately, their business outcomes.&lt;/p&gt;

&lt;p&gt;What we have discovered?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;TL;DR you probably guessed: most of them shared our enthusiasm.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In this article, I will show you the most important takeaways from &lt;a href="https://pagepro.co/blog/react-in-a-business-perspective/" rel="noreferrer noopener"&gt;2020 React Report&lt;/a&gt; that will tell you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Why did they choose React?&lt;/li&gt;
&lt;li&gt;What actually changed since they made that choice?&lt;/li&gt;
&lt;li&gt;And what are those business benefits they are taking the advantage of?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Sit back, relax, and learn how modern technology can help you make your business more efficient.&lt;/p&gt;

&lt;p&gt;Or go directly to the &lt;a rel="noreferrer noopener" href="https://pagepro.co/blog/react-in-a-business-perspective/"&gt;Report&lt;/a&gt;.&lt;/p&gt;

&lt;h1&gt;What we knew and re-discovered about React&lt;/h1&gt;

&lt;p&gt;There are many benefits of using React.js, and benefits of using React Native, however, I will use the words of our survey Guests:&lt;/p&gt;

&lt;h2&gt;React saves you time and money&lt;/h2&gt;

&lt;p&gt;As every single web technology is trying to be more efficient (make things faster and easier to do), we asked CTOs if React development is going in that direction.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--vmFdIWrz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://pagepro.co/blog/wp-content/uploads/2020/06/Q1-1024x413.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vmFdIWrz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://pagepro.co/blog/wp-content/uploads/2020/06/Q1-1024x413.png" alt="Survey result saying that React.js is &lt;br&gt;
a good technology and is moving in the right direction"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--goM7JWYX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://pagepro.co/blog/wp-content/uploads/2020/06/Tim-Baker-1024x211.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--goM7JWYX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://pagepro.co/blog/wp-content/uploads/2020/06/Tim-Baker-1024x211.png" alt="Tim Baker on the benefits of React.js"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;React boosts your team productivity&lt;/h2&gt;

&lt;p&gt;Since we started to work with React, we could experience a productivity boost. All the developers were more excited about the technology, as we could do much more with less effort.&lt;/p&gt;

&lt;p&gt;However, we wanted to make sure it’s not only our delusion.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--cGD126ID--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://pagepro.co/blog/wp-content/uploads/2020/06/Q4-1024x342.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--cGD126ID--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://pagepro.co/blog/wp-content/uploads/2020/06/Q4-1024x342.png" alt="Survey result saying that React.js is boosting team productivity and help with maintenance "&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--DjIYJr-a--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://pagepro.co/blog/wp-content/uploads/2020/06/David-1024x262.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--DjIYJr-a--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://pagepro.co/blog/wp-content/uploads/2020/06/David-1024x262.png" alt="David Panart on how React.js is boosting team productivity"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;CTOs want to use React&lt;/h2&gt;

&lt;p&gt;We could see in other surveys, as well as we have received many signals from the market, that React became and is still on the top of the most wanted and loved libraries.&lt;/p&gt;

&lt;p&gt;This time we asked if people are still interested in using React, after experiencing it in previous projects.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--hQQIF8rt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://pagepro.co/blog/wp-content/uploads/2020/06/Q11-1024x388.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--hQQIF8rt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://pagepro.co/blog/wp-content/uploads/2020/06/Q11-1024x388.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;What were the reasons behind choosing React?&lt;/h2&gt;

&lt;p&gt;We wanted to go deeper and discover more reasoning behind choosing React as a core of the technology stack.&lt;/p&gt;

&lt;p&gt;That was an open question, below the most interesting answers from our respondents:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Easy to learn and easy to use.&lt;/li&gt;
&lt;li&gt;Performance and reusability.&lt;/li&gt;
&lt;li&gt;Development time.&lt;/li&gt;
&lt;li&gt;Code sharing between web, iOS, and Android. What used to be 3 distinct codebases is now basically one.&lt;/li&gt;
&lt;li&gt;Choosing a stable and large developer ecosystem&lt;/li&gt;
&lt;li&gt;Time to market and ability to solve (most) bugs from a single code base.&lt;/li&gt;
&lt;li&gt;More in the &lt;a href="https://pagepro.co/blog/react-in-a-business-perspective/" rel="noreferrer noopener"&gt;2020 React Report&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;Key Business Takeaways&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;React is making time to market shorter and allows solving (most) bugs from a single code base, which makes software delivery more efficient.&lt;/li&gt;
&lt;li&gt;React has a stable, large developer ecosystem and a wide market of available talents.&lt;/li&gt;
&lt;li&gt;Thanks to component-oriented approach and cross-platform features React is an easily scalable way of building large-scale web &amp;amp; mobile (sometimes also desktop) apps.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;What were the doubts behind choosing React?&lt;/h2&gt;

&lt;p&gt;Just the same as in the previous question, we wanted to go deeper into reasoning, yet this time, we asked our respondents about the doubts they had before they made the choice.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Before trying React we were already using Backbone, Ember, and Angular. We were afraid that we might be spreading our skills too thin and we were not going to be actually experts in any of those technologies. Fair to say that from the above, React is the only one left in our stack.&lt;/li&gt;
&lt;li&gt;Difficult to learn, adds a layer on top of native code. Often you end up having to know native fundamentals anyway.&lt;/li&gt;
&lt;li&gt;Dependency management across platforms.&lt;/li&gt;
&lt;li&gt;A massive change in the approach meant that there is a risk that we’re spending all the time trying to skill up for nothing. However, it turned out it was time well spent.&lt;/li&gt;
&lt;li&gt;Is it stable enough?&lt;/li&gt;
&lt;li&gt;More in the &lt;a href="https://pagepro.co/blog/react-in-a-business-perspective/" rel="noreferrer noopener"&gt;2020 React Report&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;Key Business Takeaways&lt;/h3&gt;

&lt;p&gt;While implementing new technology to the company’s stack it’s important to check if:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;This particular technology is stable enough.&lt;/li&gt;
&lt;li&gt;Is it able to fulfill your company’s needs?&lt;/li&gt;
&lt;li&gt;How to train your current dev team or hire new people with solid commercial experience?&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;The biggest advantages of React&lt;/h2&gt;

&lt;p&gt;Obviously, we couldn't skip this question.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Reusable components have benefited several recent projects that we’ve been involved in.&lt;/li&gt;
&lt;li&gt;Ecosystem, dev tools, new frameworks based on React are amazing.&lt;/li&gt;
&lt;li&gt;From a front end perspective, we have much more control over the performance and perceived loading times of any React site.&lt;/li&gt;
&lt;li&gt;It allows us to add iOS and Android apps to our offering as we can now use React Native in-house.&lt;/li&gt;
&lt;li&gt;Our web portals are very high quality in terms of visible user bugs.&lt;/li&gt;
&lt;li&gt;Agility and ability to build new MVP features fast.&lt;/li&gt;
&lt;li&gt;Increased speed and decreased cost.&lt;/li&gt;
&lt;li&gt;Having one way of building front-ends, across mobile apps and web apps.&lt;/li&gt;
&lt;li&gt;More in the &lt;a href="https://pagepro.co/blog/react-in-a-business-perspective/" rel="noreferrer noopener"&gt;2020 React Report&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;Key Business Takeaways&lt;/h3&gt;

&lt;p&gt;While implementing new technology to the company’s stack it’s important to check if:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;After implementing React, organizations can increase development speed and decrease development costs.&lt;/li&gt;
&lt;li&gt;Thanks to React, a single team can manage multiple apps on different platforms.&lt;/li&gt;
&lt;li&gt;React allows companies to build a shareable, reusable library of inhouse components that can be used in different projects, prototypes, and platforms.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;And much more&lt;/h2&gt;

&lt;p&gt;This is just a small part of the whole &lt;a href="https://pagepro.co/blog/react-in-a-business-perspective/" rel="noreferrer noopener"&gt;2020 React Report.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now, we have a clear signal on the real impact of React on the business layer.&lt;/p&gt;

&lt;p&gt;What you can learn more from the Report?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What is the future of React?&lt;/li&gt;
&lt;li&gt;The best React alternatives?&lt;/li&gt;
&lt;li&gt;What are the threats of React?&lt;/li&gt;
&lt;li&gt;How hard it is to hire and onboard React developers?&lt;/li&gt;
&lt;li&gt;What is still missing in React?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Enjoy, and don’t forget to share it with people that may benefit from it.&lt;/p&gt;

&lt;p&gt;Also, send me your feedback, and if you want to take part in the next year’s survey, let me know!&lt;/p&gt;

</description>
      <category>react</category>
      <category>reactnative</category>
      <category>webdev</category>
      <category>javascript</category>
    </item>
    <item>
      <title>React Native vs Flutter</title>
      <dc:creator>Mariusz</dc:creator>
      <pubDate>Thu, 18 Jun 2020 13:05:33 +0000</pubDate>
      <link>https://dev.to/pagepro_agency/react-native-vs-flutter-2nja</link>
      <guid>https://dev.to/pagepro_agency/react-native-vs-flutter-2nja</guid>
      <description>&lt;p&gt;Demand for &lt;a rel="noreferrer noopener" href="https://pagepro.co/blog/cross-platform-apps-vs-native-apps/"&gt;cross-platform applications&lt;/a&gt; is increasing. People are constantly searching for more optimal solutions such as &lt;strong&gt;&lt;a href="https://reactnative.dev/" rel="noreferrer noopener nofollow"&gt;React Native&lt;/a&gt;&lt;/strong&gt; or &lt;strong&gt;&lt;a href="https://flutter.dev/" rel="noreferrer noopener nofollow"&gt;Flutter&lt;/a&gt;&lt;/strong&gt;, where they can create &lt;a href="https://pagepro.co/mobile-app-development.html" rel="noreferrer noopener"&gt;iOS and Android apps&lt;/a&gt; using one codebase only.&lt;/p&gt;

&lt;p&gt;While using a single codebase for two applications, you do not have to invest double time, effort, and amount to create one app which is to be implemented on two different operating systems.&lt;/p&gt;

&lt;p&gt;Many solutions have been created to deal with these scenarios but two attracted most of the audience - &lt;strong&gt;React Native&lt;/strong&gt; made by Facebook and &lt;strong&gt;Flutter&lt;/strong&gt; made by Google.&lt;/p&gt;

&lt;p&gt;These two platforms have their own pros and cons which gives them an edge over others.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Flutter&lt;/strong&gt; and &lt;strong&gt;React Native&lt;/strong&gt; allow developers to build cross-platform applications by using a single programming language. React Native has been in the market much longer. As compared to Flutter due to which this platform is a lot more matured and has developed its own community and fan base.&lt;/p&gt;

&lt;h2&gt;React Native by Facebook&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--6gsM4D4e--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://pagepro.co/blog/wp-content/uploads/2020/06/react-1.svg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--6gsM4D4e--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://pagepro.co/blog/wp-content/uploads/2020/06/react-1.svg" alt="React Native logo" width="193" height="173"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Facebook's product, &lt;strong&gt;React Native&lt;/strong&gt; is a lot more mature as compared to other choices such as Ionic, Xamarin, PhoneGap, etc. It has a strong community that provides solutions to all sorts of problems.&lt;/p&gt;

&lt;p&gt;At this point in time, React Native is renowned as the world champion. This powerful Javascript framework is built using React library which allows you to develop iOS and Android apps using a single codebase.&lt;/p&gt;

&lt;p&gt;People actively use it all over the world and most of the organizations made it their premium choice for their mobile applications.&lt;/p&gt;

&lt;p&gt;Funny thing is that Facebook started as a hackathon project in 2013, but in 2015 it became public for the masses.&lt;/p&gt;

&lt;h2&gt;Flutter by Google&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--q3hG0YM4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://pagepro.co/blog/wp-content/uploads/2020/06/flutter-logo-sharing.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--q3hG0YM4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://pagepro.co/blog/wp-content/uploads/2020/06/flutter-logo-sharing.png" alt="Flutter logo" width="374" height="184"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Flutter&lt;/strong&gt; is the cross-platform framework that develops mobile applications by using Dart language.&lt;/p&gt;

&lt;p&gt;Both the language and framework are developed by Google and a lot of efforts and time were invested so that desired applications can be created in the easiest way which serves their purpose completely.&lt;/p&gt;

&lt;p&gt;In 2017, the initial alpha phase of Flutter was started which makes it a lot younger than React Native.&lt;/p&gt;

&lt;p&gt;Though it is new, its features and competency made it a prominent choice in much less time.&lt;/p&gt;

&lt;h2&gt;Head to Head Comparison between React Native and Flutter&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table class="has-fixed-layout"&gt;
&lt;thead&gt;&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th class="has-text-align-center"&gt;React Native&lt;/th&gt;
&lt;th class="has-text-align-center"&gt;Flutter&lt;/th&gt;
&lt;/tr&gt;&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Programming Language&lt;/strong&gt;&lt;/td&gt;
&lt;td class="has-text-align-center"&gt;JavaScript&lt;/td&gt;
&lt;td class="has-text-align-center"&gt;Dart&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Created by&lt;/strong&gt;&lt;/td&gt;
&lt;td class="has-text-align-center"&gt;Facebook&lt;/td&gt;
&lt;td class="has-text-align-center"&gt;Google&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Main Structure&lt;/strong&gt;&lt;/td&gt;
&lt;td class="has-text-align-center"&gt;Flux and Redux&lt;/td&gt;
&lt;td class="has-text-align-center"&gt;BLoC&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Hot Reload&lt;/strong&gt;&lt;/td&gt;
&lt;td class="has-text-align-center"&gt;Supported&lt;/td&gt;
&lt;td class="has-text-align-center"&gt;Supported&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Release Date&lt;/strong&gt;&lt;/td&gt;
&lt;td class="has-text-align-center"&gt;Jan 2015&lt;/td&gt;
&lt;td class="has-text-align-center"&gt;May 2017&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Performance&lt;/strong&gt;&lt;/td&gt;
&lt;td class="has-text-align-center"&gt;Native-like&lt;/td&gt;
&lt;td class="has-text-align-center"&gt;Native-like&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Code Reusability&lt;/strong&gt;&lt;/td&gt;
&lt;td class="has-text-align-center"&gt;Up to 90%&lt;/td&gt;
&lt;td class="has-text-align-center"&gt;Up to 90%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Major Use Cases&lt;/strong&gt;&lt;/td&gt;
&lt;td class="has-text-align-center"&gt;Facebook &lt;br&gt;Pinterest&lt;br&gt;Instagram&lt;/td&gt;
&lt;td class="has-text-align-center"&gt;Alibaba&lt;br&gt;Groupon&lt;br&gt;Google Ads&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;Pros and Cons&lt;/h2&gt;

&lt;p&gt;We will be having a look on a few advantages and disadvantages which (I hope) allow you to make a wise and calculated decision.&lt;/p&gt;

&lt;p&gt;Both the platforms are strong enough to be used, but there are certain features that may work better for you while others need to be considered before you will make your decision in that regard.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table class="has-fixed-layout"&gt;&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td class="has-text-align-center"&gt;&lt;strong&gt;React Native&lt;/strong&gt;&lt;/td&gt;
&lt;td class="has-text-align-center"&gt;&lt;strong&gt;Flutter&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Pros&lt;/strong&gt;&lt;/td&gt;
&lt;td class="has-text-align-center"&gt;Having a hot reload feature allows it to have fast coding.&lt;br&gt;&lt;br&gt;One codebase for two mobile platforms&lt;br&gt;&lt;br&gt;Use known and widely used language - Javascript&lt;br&gt;&lt;br&gt;Facilitates to reuse the code and save cost&lt;br&gt;&lt;br&gt;Mature platform&lt;br&gt;&lt;br&gt;Supported by an active and vast community&lt;br&gt;&lt;br&gt;Easy to learn and adapt&lt;br&gt;&lt;br&gt;Less Testing&lt;br&gt;&lt;br&gt;Robust Performance&lt;/td&gt;
&lt;td class="has-text-align-center"&gt;Hot reload which means fast coding&lt;br&gt;&lt;br&gt;Requires one codebase for two different platforms&lt;br&gt;&lt;br&gt;Requires 50% less testing&lt;br&gt;&lt;br&gt;User-friendly designs&lt;br&gt;&lt;br&gt;Faster app/product development&lt;br&gt;&lt;br&gt;Less Cod&lt;br&gt;&lt;br&gt;Ideal for MVPs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Cons&lt;/strong&gt;&lt;/td&gt;
&lt;td class="has-text-align-center"&gt;Limited freedom of choice for the developer&lt;br&gt;&lt;br&gt;UI is fragile&lt;br&gt;&lt;br&gt;Apps require additional coding than the native ones&lt;br&gt;&lt;br&gt;Abandoned packages and libraries&lt;br&gt;&lt;br&gt;Not native&lt;/td&gt;
&lt;td class="has-text-align-center"&gt;The risk involved in the platform&lt;br&gt;&lt;br&gt;The limited size of the developer community&lt;br&gt;&lt;br&gt;Libraries and support is limited as compared to React Native&lt;br&gt;&lt;br&gt;Requires continuous integration support&lt;br&gt;&lt;br&gt;Size of the App&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;Performance of React Native and Flutter&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--JS-cPuv3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://pagepro.co/blog/wp-content/uploads/2019/11/sebastiaan-stam-4lqMd_XBlfU-unsplash-1024x539.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--JS-cPuv3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://pagepro.co/blog/wp-content/uploads/2019/11/sebastiaan-stam-4lqMd_XBlfU-unsplash-1024x539.jpg" alt="performance on the car counter"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;While talking about &lt;a href="https://pagepro.co/" rel="noreferrer noopener"&gt;cross-platform applications&lt;/a&gt;, their performance and User-interface is considered as the biggest challenge.&lt;/p&gt;

&lt;p&gt;You have to provide a seamless experience which the user has while using the native application.&lt;/p&gt;

&lt;p&gt;While working around the platform of your choice, developers need to make sure that their product provides quick performance, pixel perfect design, and intuitive navigation.&lt;/p&gt;

&lt;p&gt;If you are using Google’s platform or Facebook’s you need to consider the efficiency of how you communicate with the native modules.&lt;/p&gt;

&lt;p&gt;In the case of &lt;a href="https://pagepro.co/react-native-development.html" rel="noreferrer noopener"&gt;React Native development&lt;/a&gt;, the app’s performance slows down as JavaScript needs to bridge, in order to carry out the functions, while in Flutter, Dart is built with necessary components that give immediate access.&lt;/p&gt;

&lt;p&gt;We can clearly see that Flutter has an edge in providing a sharp performance to its users.&lt;/p&gt;

&lt;h2&gt;UI and UX&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--4oIEugBh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://pagepro.co/blog/wp-content/uploads/2019/10/photo-1522542550221-31fd19575a2d-1024x683.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--4oIEugBh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://pagepro.co/blog/wp-content/uploads/2019/10/photo-1522542550221-31fd19575a2d-1024x683.jpeg" alt="user experience planning picture"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Most of the effectiveness of these platforms depend upon their user interface design and how things are made easy for the users and developers with the additional features provided.&lt;/p&gt;

&lt;p&gt;Flutter provides its own sets of widgets which allows it to implement the design of certain platforms or to customize them easily.&lt;/p&gt;

&lt;p&gt;While React Native only uses native UI controllers, though it has an additional ReactJS library which is also rich in UI elements. If you remove this library from the platform then you leave React Native with almost zero UI elements at our disposal.&lt;/p&gt;

&lt;p&gt;So, in the case of UI and UX, Flutter is surely winning the game.&lt;/p&gt;

&lt;h2&gt;Learning Curve&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--BshkPKd---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://pagepro.co/blog/wp-content/uploads/2020/01/patrick-tomasso-Oaqk7qqNh_c-unsplash.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--BshkPKd---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://pagepro.co/blog/wp-content/uploads/2020/01/patrick-tomasso-Oaqk7qqNh_c-unsplash.jpg" alt="lots of papers"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;React Native is based on Javascript which is known by the masses whereas Flutter incorporates Dart which is relatively new and has a limited set of developers as compared to the former one.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://pagepro.co/" rel="noreferrer noopener"&gt;Mobile developers&lt;/a&gt; can easily master JS and develop the desired product in a relatively less amount of time. Finding a programmer for the project would also be much easier as the talent pool is vast.&lt;/p&gt;

&lt;p&gt;React Native also supports the massive collection of libraries and ready-made components which make the job a lot more easy. More than that, the reusability of React Native components makes you save a lot of time during the execution phase, and shorten your product time-to-market.&lt;/p&gt;

&lt;p&gt;According to this aspect, RN scores the point.&lt;/p&gt;

&lt;h2&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;It is clearly stated that React Native is more popular and widely used due to its feasibility and extensive support, but it does not mean that Flutter lags behind.&lt;/p&gt;

&lt;p&gt;Flutter is new as compared to RN but soon it is may going to make the buzz due to its features and efficiency.&lt;/p&gt;

&lt;p&gt;React Native is currently more stable but we can surely see the growth curve of Flutter too, it is simply a matter of time when both these platforms will have their own significant set of audiences.&lt;/p&gt;

&lt;p&gt;These both are ideal choices to develop applications in a timely manner while being cost-effective solutions.&lt;/p&gt;

&lt;p&gt;Every application requires different points to be considered, so the decision entirely depends upon the organization and the developer.&lt;/p&gt;

&lt;p&gt;At this point of time, no one can predict the future regarding the winner but we can wait and watch how things turn and which platform provides more competent solutions to the problems.&lt;/p&gt;

</description>
      <category>reactnative</category>
      <category>webdev</category>
      <category>flutter</category>
      <category>mobile</category>
    </item>
  </channel>
</rss>
