# Prepr Documentation - Full Export > Complete Prepr CMS documentation in one file. --- # Start building with Prepr This is the place to learn all about Prepr. Explore the topics below to start learning or create your [free account here](https://signup.prepr.io) if you haven't done so already. If you need any help, don't hesitate to reach out: [Join our Slack](https://slack.prepr.io) or [Reach out to our support team](https://prepr.io/support). ## Connect a front-end framework ## More resources Source: https://docs.prepr.io/index --- # Quick start guide *Estimated duration: 15-30 minutes* ## Introduction Prepr allows you to develop a dynamic, data-driven, web application with ease. This tutorial explains how to get started with Prepr. We will cover all the basics: modeling content types, adding content and images and retrieving content using the API. Follow the step-by-step guide below. ## Use case This tutorial explains how to manage articles and author profiles in Prepr and retrieve that content using the GraphQL API. For example, to create a blog. You can apply these principles to all kinds of situations.  ## Step 1: Create an environment If you haven't already done so, go to https://signup.prepr.io/ and sign up for a Prepr account. 1. After you sign up, you will be prompted to add an environment. Enter a **Name** and choose the **Default locale** and **Development stage**.  2. On the next screen, you will be prompted to either load demo data or to start from scratch. While importing demo data can help you explore Prepr features with preset schema and content items, for the purpose of this tutorial we recommend starting from scratch to experience the whole setup process yourself. To get a clean environment, click **Start from scratch**.  That’s it. You’ve created your first environment in Prepr. In the next step, you can add models and fields for our blog use case. ## Step 2: Create content models A headless CMS allows you to define a structure for your content according to your needs. We call that content modeling. For this example, you need an **Article** model and a **Person** model.  Let’s create these models in Prepr: 1. Click the **Schema** tab to open the *Schema Editor*. 2. Then, click the **+ Add model** button. 3. Choose **Start from scratch**, click **Next**, choose **Multi-item model**, and click **Next**. 4. Enter *Person* in the **Display name** field and click **Next** and **Save**. Check out the [Models doc](/content-modeling/managing-models#manage-settings) for more details on additional options.  5. Drag and drop the **Text** field type, from the list on the right into your model. a. Enter *Name* in the **Display name** field and click **Save**. 6. Drag and drop another **Text** field type, from the list on the right into your model. a. Enter *Bio* in the **Display name** field. b. Click the **Settings** tab. c. Select *Text area* and click **Save**. 7. Drag and drop the **Assets** field type, from the list on the right into your model. a. Choose the **Multi-asset field** option. b. Enter *Image* in the **Display name** and click **Save**. Your Person model should now look like this:  Now you can add the Article model. 1. Click the **+ Add model** button on the left. 2. Choose **Start from scratch**, click **Next**, choose **Multi-item model**, and click **Next**. 3. Enter *Article* in the **Display name** field, click **Next** and **Save**. Check out the [Models doc](/content-modeling/managing-models#manage-settings) for more details on additional options. Your model should look something like this:  And add the fields: 4. Drag and drop the **Text** field type, from the list on the right into your model. a. Enter *Headline* in the **Display name** field and click **Save**. 5. Drag and drop another **Slug** field type, from the list on the right into your model. a. Click **headline** in the box below to fill the Slug template with `{headline}`. b. Click **Save**. Now we’re going to add the author field. This is not a text field, but a reference to the Person model you created earlier. A reference field allows you to link to other content items, as in this case to a Person. 6. Drag and drop the **Content reference** field type, from the list on the right into your model. a. Enter *Author* in the **Display name** field. b. Select the *Person* model and click **Save**.  7. Next, add the rest of the fields below in the same way as described above: - *Intro* - **Text** field - *Image* - **Assets** field - *Content* - **Dynamic content** field - *Tags* - **Tags** field See an overview of [all field types](/content-modeling/field-types). Your model should look like the image below.  ## Step 3: Create content items Now that you've created the models, you can add content items. Start by adding a *Person*: 1. Go to the **Content** tab, click the **Add item** button and choose **Person**. 2. Fill out the **Name** and **Bio** fields. 3. Drag and drop an image into the **Image** field or click it to add an image from your local storage.  6. Click the **Publish** dropdown and select the **Publish and close** option. Now, add an article: 1. Click the **Add item** button again. 2. This time, select **Article**. 3. Enter a **Headline**. You will notice the slug field automatically being populated. Copy this slug value to retrieve your article in [Step 5](#step-5-retrieve-a-single-article-from-the-api). 4. Click the **+ Person** link to choose and add a person to the *Author* field.  Now fill in the remaining fields. 6. Add some text and images to the *Content* field. 7. Add some tags in the *Tags* field. Add tags by selecting an existing tag in the list, or adding a new tag and clicking **Enter**. 8. Click the **Publish** dropdown and select the **Publish and close** option. The next step is to retrieve the content items from the API so you can display the content in your web application. ## Step 4: Retrieve articles from the API The easiest way to experience content retrieval through the API is to use the API explorer: 1. Click the icon and choose the **Access tokens** option. 2. Click to open the *GraphQL Production* token details. 3. Open the API explorer by clicking the **Open API Explorer** link.  Make sure you see a green dot and your access token at the end of the url. If you cannot connect, please contact support.  With the explorer, you can easily create and test API queries. Let’s create a query to retrieve a list of all articles: 4. Add the following query ```graphql copy query { Articles { items { _id headline } } } ``` Note that you can retrieve the ID for all content items using the system field *\_id*. You can recognize system fields by the underscore in front of the field name. Check out [all system fields](/graphql-api/schema-system-fields) for more information. 5. Click **Run** to execute the query The result should look something like this: ```json copy { "data": { "Articles": { "items": [ { "_id": "4fcad70d-2beb-4886-bd8d-1753020bf315", "headline": "How to get the best deals : Insider tips and tricks" } ] } } } ``` As you can see, the response includes a list of all the items. At the moment, there is only one article, which is listed including its ID and headline. Let's expand the query so that you retrieve the other fields as well. ```graphql copy query { Articles( where: { _publish_on_gt : "2025-06-15T09:00:00+00:00" } ) { items { _id _slug _publish_on author { _id name image { url(width:800) } } headline image { url(width: 1000) } intro tags { body } } } } } ``` In the query above, we added a condition to get all articles published on or after June 15th, 2025. This query includes the following fields that we want to see in the result: - *\_slug* field - *\_publish\_on* field to retrieve the publication date - *author* field to retrieve reference fields ([learn more](/graphql-api/schema-field-types#content-reference)) - *image* field to retrieve assets ([learn more](/graphql-api/schema-field-types#assets)) - *content* field to retrieve a dynamic content field ([learn more](/graphql-api/schema-field-types-dynamic-content-field)) - *tags* field to retrieve tags ([learn more](/graphql-api/schema-field-types#tag)) Check out the documentation for [all field types](/graphql-api/schema-field-types) and how to retrieve [multiple content items](/graphql-api/fetching-collections) for more information. - Run the query. The response should look something like this: ```json copy { "data": { "Articles": { "items": [ { "_id": "38a05b5c-98cf-4275-8d2b-3748f49cc104", "_slug": "how-to-get-the-best-deals-insider-tips-and-tricks", "_publish_on": "2025-10-07T12:08:00+00:00", "author": [ { "_id": "dee58849-bb0a-4ceb-a288-7adc9e623602", "name": "Emma Carter", "image": { "url": "https://ml98.stream.prepr.io/6iku17cg8lc8/w_800/emma-carter-profile.jpg" } } ], "headline": "How to get the best deals : Insider tips and tricks", "image": { "url": "https://ml98.stream.prepr.io/6i57ud05jnjq/w_1000/business-deal-photo.jpg" }, "intro": "Want to lease a car without overpaying? Follow these expert tips to negotiate the best lease deal, avoid common pitfalls, and maximize your savings.", "tags": [ { "body": "car deals" }, { "body": "tips and tricks" } ] } ] } } } ``` And voila, a JSON response containing all the data from your content items. We just queried a list of articles that you can use to show on a blog overview page. On that page, you give each item a unique URL based on the slug—for example: ``` https://yourdomain.com/articles/how-to-get-the-best-deals-insider-tips-and-tricks ``` ## Step 5: Retrieve a single article from the API You want to show the whole article when a visitor clicks the link. Retrieving a single content item can be done using the below query. Replace the slug value with the value that you copied in [Step 3](#step-3-create-content-items). ```graphql copy query { Article( slug: "how-to-get-the-best-deals-insider-tips-and-tricks") { _id headline } } ``` In the query above, we specify a condition to return an item with the matching slug. Update the slug value in quotes to match the slug of the article that you created. When you run this query you get the following result: ```json copy { "data": { "Article": { "_id": "38a05b5c-98cf-4275-8d2b-3748f49cc104", "headline": "How to get the best deals : Insider tips and tricks" } } } ``` The last thing you need to know is how to retrieve the article content. Expand the query like this: ```graphql copy query { Article(slug: "how-to-get-the-best-deals-insider-tips-and-tricks") { _id headline author { _id name image { url(width:800) } } intro image { url(width: 1000) } content { ... on Text { format body } ... on Assets { items { url(width:600) } } } tags { body } } } ``` You've already seen most of the fields when you retrieved the article list. The content field is new. The preceding query shows how to retrieve a dynamic content field. Per element type, you fetch the information. In this case, for text elements and assets only, however, there are many more element types. Check out the [dynamic content field documentation](/graphql-api/schema-field-types-dynamic-content-field) for all the details. Here’s the result: ```json copy { "data": { "Article": { "_id": "38a05b5c-98cf-4275-8d2b-3748f49cc104", "headline": "How to get the best deals : Insider tips and tricks", "author": [ { "_id": "dee58849-bb0a-4ceb-a288-7adc9e623602", "name": "Emma Carter", "image": { "url": "https://ml98.stream.prepr.io/6iku17cg8lc8/w_800/emma-carter-profile.jpg" } } ], "intro": "Want to lease a car without overpaying? Follow these expert tips to negotiate the best lease deal, avoid common pitfalls, and maximize your savings.", "image": { "url": "https://ml98.stream.prepr.io/6i57ud05jnjq/w_1000/business-deal-photo.jpg" }, "content": [ { "format": null, "body": "
Leasing a car can be a great way to drive a new vehicle without the high upfront cost of purchasing. However, not all lease deals are created equal. If you want to save money and get the most value, follow these expert tips to secure the best lease deal possible.
" }, { "format": null, "body": "1. Understand the Key Lease Terms
" }, { "format": null, "body": "Before negotiating, it’s essential to understand how leases work. Here are the critical terms you should know:
" }, { "format": null, "body": "• Capitalized Cost (Cap Cost) – The vehicle’s price before lease calculations. Like when buying, this can be negotiated down.
" }, { "format": null, "body": "• Residual Value – The car’s estimated value at the end of the lease. Higher residual values mean lower monthly payments.
" }, { "format": null, "body": "• Money Factor – Equivalent to the interest rate on your lease. The lower, the better.
" }, { "format": null, "body": "• Mileage Limit – Most leases have annual limits (e.g., 10,000–15,000 miles). Exceeding this incurs extra charges.
" }, { "format": null, "body": "2. Negotiate the Capitalized Cost
" }, { "format": null, "body": "Many people assume lease prices are fixed—they’re not! You can negotiate the cap cost just like when buying a car. Research the market price of the vehicle and ask for a discount. The lower the price, the lower your monthly lease payments.
" }, { "format": null, "body": "3. Look for Manufacturer Lease Specials
" }, { "format": null, "body": "Car manufacturers frequently offer special lease deals, reducing monthly payments, down payments, or interest rates. These can include:
" }, { "format": null, "body": "• Cash rebates
" }, { "format": null, "body": "• Loyalty discounts
" }, { "format": null, "body": "• Zero down-payment leases
" }, { "format": null, "body": "Check official websites and dealership promotions for these offers.
" }, { "format": null, "body": "4. Choose a Car with a High Residual Value
" }, { "format": null, "body": "Cars that retain their value well will have a higher residual value, leading to lower monthly payments. Brands like Toyota, Honda, and Lexus typically have strong resale values.
" }, { "format": null, "body": "5. Understand Lease Fees and Extra Costs
" }, { "format": null, "body": "Be aware of the following potential extra costs:
" }, { "format": null, "body": "• Acquisition Fee – A fee for setting up the lease.
" }, { "format": null, "body": "• Disposition Fee – Charged at the end of the lease if you return the car.
" }, { "format": null, "body": "• Excess Mileage Charges – Avoid these by choosing a lease with the right mileage limit.
" }, { "format": null, "body": "6. Consider a One-Pay Lease
" }, { "format": null, "body": "Instead of making monthly payments, some dealerships offer a single lump-sum payment lease. If you can afford it, this may save you thousands in interest fees.
" }, { "format": null, "body": "7. Final Tip: Read the Lease Agreement Carefully
" }, { "format": null, "body": "Before signing, review every detail of the lease to avoid hidden costs. If anything is unclear, ask for clarification.
" } ], "tags": [ { "body": "car deals" }, { "body": "tips and tricks" } ] } } } ``` For more details check out the [fetching single content items](/graphql-api/fetching-single-items) API reference. Congratulations, you have completed your first steps with Prepr. From modeling and creating content items to retrieving content using the API. With that, you have mastered the basics of Prepr. ## Step 6: Connect your front end The next step is to connect your web application. We have guides for all major front-end frameworks to quickly get you up and running. - [Next.js](/connecting-a-front-end-framework/nextjs) - [Nuxt](/connecting-a-front-end-framework/nuxtjs) - [Laravel](/connecting-a-front-end-framework/laravel) - [Angular](/connecting-a-front-end-framework/angular) - [Gatsby](/connecting-a-front-end-framework/gatsby) - [Node.js](/connecting-a-front-end-framework/nodejs) - [PHP](/connecting-a-front-end-framework/php) - [React](/connecting-a-front-end-framework/react) - [Vue.js](/connecting-a-front-end-framework/vuejs) ## Want to learn more? Of course, there is much more to explore. For example, with Prepr, you can perform A/B testing, present recommendations and personalize the customer experience. For more advanced topics, please refer to the rest of the documentation, or contact one of our specialists. Check out the following chapters: - [A/B testing](/ab-testing) - [Personalization](/personalization) - [Recommendations](/recommendations) ## Schedule a free consultation Do you want to get started but still have questions or want a demo? [Schedule a free call](https://prepr.io/get-a-demo) with a Prepr solution engineer. During the consultation we can provide recommendations on topics like: - Content modeling for the desired use case - Working with multiple environments, websites and languages - Creating personalized experiences for your website visitors - A/B testing and other optimization strategies Source: https://docs.prepr.io/quick-start-guide --- # Changelog Beautiful new features and important updates are added to Prepr on a daily basis. This changelog gives you an insight into the most eye-catching releases. Be aware that updates can be rolled out in phases so they may not always be available in all Prepr environments at the same time. **Latest** | [2024](/stay-updated/changelog2024) | [2023](/stay-updated/changelog2023) ## Introducing goals for personalization and A/B testing *December 17th, 2025* Goals allow you to see the overall impact of your personalization and A/B testing experiments on conversions. You can create clear conversion definitions by combining multiple behavioral conditions.  This means you can optimize your website not just for click-through rate (CTR), but for deeper insights. So you can better understand what works for customer experience, boosting engagement and conversion rates. Check out the [Goals setup guide](/personalization/defining-goals) for more details. ## New *Content tree* layout *December 16th, 2025* You can now view your overall structure of content items, by their slug (URL) value, as a visual tree layout. The *Content tree* layout provides instant, hierarchical context for how an item relates to other content.  This means improved navigation between content items and less time searching for related items. For more details, check out the [content tree setup guide](/project-setup/setting-up-environments#content-tree-parent-slug-format). ## Generate AI suggestions for personalized variants *December 9th, 2025* When adding personalized content, you can now get AI suggestions for adaptive content based on a customer segment you choose. The auto-generated variant suggestions give you inspiration to quickly create and fine-tune your adaptive content.  The AI generation of adaptive content allows you to automate normally repetitive work of re-writing content for multiple customer segments. This means you can scale your personalization efforts in much less time. Check out the [Adaptive content guide](personalization/managing-adaptive-content#add-an-adaptive-content-element) for more details. ## Dynamic initial values for text fields *December 8th, 2025* With dynamic initial values you can set up text fields to prefill based on other field values helping editors speed up content creation. For example, for *Post* content items, you can define the initial value for the SEO meta description field to be prefilled with the Post excerpt value the editor enters in the content item.  This means simpler data entry and ensures consistency across content items. Check out the [text field settings](/content-modeling/field-types#text-field) for more details. ## Improved GraphQL caching *November 27th, 2025* We've improved our GraphQL API caching mechanism to significantly improve developer experience and workflow reliability when making changes to your *Schema*. Now, the GraphQL API automatically refreshes the cache when you make any change to a schema. This means that your changes are immediately applied when you regenerate your TypeScript types in front-end application. Check out the [GraphQL API caching doc](/graphql-api/caching) for more details. ## Introducing granular permissions to manage content items *November 24th, 2025* With granular content permissions, you can now precisely define a user role to allow users to only create, read, update, delete, manage comments, publish and unpublish content items.  In doing so, you have enhanced security and clearer workflow for every user reducing the risk of accidental errors. Check out the [user role guide](/project-setup/managing-roles-and-permissions#add-or-edit-roles) for more details. ## Prepr now available in French *November 24th, 2025* With Prepr now available in French, your users in French-speaking regions or those who prefer French can use Prepr in their native language. You can enable the French UI in the environment settings or each user can set their preferred interface language to French in their [account profile](/project-setup/managing-users#set-language-preferences).  This feature provides a more intuitive and comfortable user experience, leading to greater understanding, and reduced errors for French-speaking users. For more details, check out the [environments settings](/project-setup/setting-up-environments#manage-environment-settings). ## Making slug prefix read-only *November 5th, 2025* We've introduced a new option to make the first part of a slug read-only. When you enable this option in the *Slug* field settings, editors can only edit the part of the slug after the last `/`.  With this feature, you enforce consistent slugs ensuring clean and accurate content item URLs and prevent broken links when editors need to update slug values manually. Check out the [*Slug* field reference](/content-modeling/field-types#slug-field) for more details. ## Conditional visibility by environment *October 23rd, 2025* You can now control field visibility per environment when using a shared schema. This new option lets you choose which environments to show certain fields, ideal for multi-site or multi-brand setups where fields differ slightly between environments.  It makes managing shared schemas much more flexible and keeps your content models clean and relevant across all sites. Check out the [shared schema guide](/project-setup/architecture-scenarios/shared-schema#choose-field-visibility-for-environments) for more details. ## New SSO login options *October 23rd, 2025* You can now integrate your preferred identity provider (IdP) to Prepr using one of our new SSO options. In addition to *Microsoft Entra ID* (formerly *Azure Active Directory*), you can now set up single sign-on for your Prepr users using *Google Workspace*, or any identity provider with either the *SAML 2.0* or *OpenID Connect* open standards.  By setting up one of these options, you enhance security and give your users an improved login experience. Check out the [updated SSO guide](/project-setup/setting-up-sso) for more details. ## Improved navigation user interface *October 21st, 2025* We've improved our navigation with a cleaner and more intuitive interface. The environment selector is now on the left and you'll see a prominent banner to indicate when you're logged into a test or development environment. You'll also find the *Settings* in a new location on the right when you click the icon.  The updated navigation allows you to work more confidently in Prepr with the clear indication of the environment and type of environment you're working in. For more details, check out the [environments guide](/project-setup/setting-up-environments). ## Publish nested content items *October 21st, 2025* You now have the option to publish all linked child items in one go when publishing a parent content item.  This prevents broken or incomplete pages and ensures all linked content goes live at the same time. So, you save time and avoid errors by publishing the whole content structure in a single action. Check out the [content management docs](/content-management/managing-content/managing-content-items#publish-a-content-item) for more details. ## Introducing filter options for content selection *October 16th, 2025* You can now see filter options in the content item selection modal when you choose to add related content items to your content item.  These options allow you to quickly narrow down large lists of content items by key criteria like model, category, or workflow stage. So, you save time and ensure you link related content items more accurately. Check out the [adding content references doc](/content-management/managing-content/creating-rich-content#adding-content-references) for more details. ## Introducing custom workflow stages *October 8th, 2025* We've added the ability for you to add custom workflow stages to your Prepr collaboration workflow on the *Environment* detail page. For example, when you have translation tasks for content items, you could add stages like *Translate* and *Review translation*.  This means you can seamlessly align the Prepr workflow with your own content creation process. For more details, check out the [environment settings doc](/project-setup/setting-up-environments#workflow-stages). ## New GraphQL API version 2025-10-07 is available *October 7th, 2025* Our newest GraphQL API version brings you additional localization support with the following new features: - A new root query field `DefaultLocale` returns the environment's default locale. - `_locale` in the Interface `Model` - `_locales` in the Interface `Model` Check out the [GraphQL API upgrade guide](/graphql-api/upgrade-guide#version-2025-10-07) for more details. ## Introducing the Shopify integration *October 2nd, 2025* Our new Shopify integration lets your team easily include products, variants and collections in content items.  This means your content editors can work more efficiently and error-free by simply choosing the relevant Shopify entries directly in Prepr. For more details, check out the [Shopify integration guide](/integrations/shopify). ## Introducing the BigCommerce integration *October 2nd, 2025* Now you can integrate Prepr with BigCommerce to seamlessly add product details to your content.  With this integration, your content editors can save time by simply choosing BigCommerce products directly in Prepr. For more details, check out the [BigCommerce integration guide](/integrations/bigcommerce). ## Automatically review your content items *October 1st, 2025* Introducing *Content check*, a new feature that automatically validates the quality of your content and provides AI-powered suggestions for improvements.  In just one click, it checks for missing required fields, broken links and options to boost your SEO. Try out this new tool, part of our continuous efforts to optimize the quality of the content in less time, and [let us know your thoughts](https://prepr.io/feedback). Check out the [Reviewing content guide](/content-management/reviewing-content#content-check) for more details. ## Introducing the Snitcher integration *September 15th, 2025* With the new Snitcher integration, you can easily connect Prepr to Snitcher, a B2B website visitor identification platform. This integration allows you to segment website visitors based on their company profile.  So, you can personalize content for an enhanced user experience for your B2B audience. Check out the [Snitcher integration guide](/integrations/snitcher) for more details. ## New sign-in option to use passkeys *September 10th, 2025* We've released a new sign-in option to use passkeys.  This feature gives you an alternative to using the email, password combination and 2FA. This means you can log in securely and conveniently without needing to manually manage passwords or additional authentication steps. For more details, check out the [account profile settings](/project-setup/managing-users#add-passkeys). ## New option to hide models from *Add item* list *September 3rd, 2025* You can now simplify the content creation experience by reducing the list of models content editors need to select from. To make this possible, choose which models to hide from the selection list in the *Add item* modal. For example: Hide models for child content items like an *Author* or *Category* which are usually created when editing an *Article*.  By disabling the visibility of certain models, you ensure content editors only see what's relevant to them. Check out the [Model settings](/content-modeling/managing-models#settings) for more details. ## Organize your segments into folders *August 28th, 2025* You can now group your segments into folders, making it easier to manage and navigate when working with many customer profiles. Instead of scrolling through a long alphabetical list, related segments can be organized together in a structured way.  This update gives you a simple way to stay organized and find the right segment faster. For more details, check out the [Managing segments guide](/personalization/managing-segments#organize-segments-into-folders). ## Matching HubSpot contacts to Prepr customer profiles *August 25th, 2025* Prepr now automatically matches your HubSpot contacts to existing Prepr customer profiles, putting them in their matching HubSpot segments and updating their company name and email address. This way, you ensure your HubSpot customer profiles are always accurate and up to date.  With this release, you can create personalized, data-driven content even more precisely. Check out the [HubSpot integration](/integrations/hubspot) guide for more details. ## Algolia Auto sync option *August 20th, 2025* With the new Algolia **Auto sync** option you can choose to disable automatic synchronization of content to Algolia directly in Prepr.  This gives you more control and helps you prevent issues with the web app search functionality resulting from bulk updates, for example. In other words, ensure a stable search experience for your users. Check out the [Algolia integration guide](/integrations/algolia#connect-prepr-to-algolia) for more details. ## A/B testing article headlines *July 30th, 2025* You can now run experiments for article headlines by adding an A/B test directly to a header or title *Text field*. For example, to test headlines in a list of recommended articles on the home page. Now you can measure which headlines encourage readers to open the article they want to read.  Optimize performance with surgical precision, driving higher engagement and conversion rates. To enable A/B testing on a text field check out the [Text field settings](/content-modeling/field-types#ab-testing). ## New Prepr Next.js package version is available *July 22nd, 2025* We're happy to bring you a new and improved version of the **Prepr Next.js package**, a toolkit to streamline your personalization and A/B testing implementation for your Next.js front end. We’ve redesigned the *Preview Bar* into a less intrusive floating toolbar, giving content editors a cleaner, distraction-free preview experience.  In addition to previewing different A/B test variants and personalized experiences, content editors can now enable **Edit mode** to highlight any element in the preview page. When enabled, they can then simply hover over elements to reveal links that open the corresponding item directly in Prepr for quick updates. Check out the [Prepr Next.js package guide](/prepr-nextjs-package) for more details. ## Improved handling of conditional required fields *July 18th, 2025* We’ve released an important update to ignore the required field validation when a field is conditionally hidden. Previously, if a required field was hidden due to conditional logic, it would still prevent a content item from being published. This often led users to mark fields as non-required simply to avoid validation errors during publishing. With today’s update, a required field is only enforced when it is visible to the content editor. If the field is hidden due to a conditional setting, it'll be treated as not required in the API schema. However, fields that are always visible remain required both in the editor and the API.  This improvement is enabled by default for new customers, while existing environments can activate the feature manually in the **Environment** settings page. Check out the [environment settings](/project-setup/setting-up-environments#manage-environment-settings) for more details. ## Introducing content item views *July 16th, 2025* With the new content item views, we're introducing a cleaner interface to manage content visibility. This new feature allows you to create, organize, and access your own tailored views.  The new content item views replace how you previously used saved filters for content items. You can save time by creating views that are most relevant for you, while your team can collaborate more effectively with shared and role-based views. Check out the [managing content doc](/content-management/managing-content/managing-content-items#views) for more details. ## Introducing the *Needs attention* overview *July 16th, 2025* To enhance the reliability and quality of stored content, we've added a content quality checker to find content items with broken links or content items that could not be published. You can find the list of these content items in the new *Needs attention* view.  These quality indicators help prevent broken user experiences on live websites and empower content teams to quickly identify and resolve issues before publication. Check out the [managing content doc](/content-management/managing-content/managing-content-items#manage-content-quality) for more details. ## Recovering deleted content items *July 16th, 2025* With the new *Deleted* view, you can now quickly find and restore deleted items with just a few clicks, for example, if you deleted an item accidentally.  Check out the [managing content doc](/content-management/managing-content/managing-content-items#recover-a-deleted-item) for more details. ## Two-factor authentication (2FA) required for Owners and Admins *July 1st, 2025* To strengthen account security, 2FA is required for all users with an *Owner* or *Admin* role in a paid Prepr organization as of July 1, 2025. If 2FA is not enabled, users will be prompted to set it up before accessing Prepr. SSO users are exempt from this requirement. Check out the [Activating two-factor authentication](/project-setup/managing-users#activate-two-factor-authentication) guide for more details. ## New Identify event to store identity provider user IDs *June 25th, 2025* The new `Identify` event stores a user's unique ID from your Identity Provider directly in their matching customer profile in Prepr. ```js copy prepr('event', 'Identify', 'external-profile-ID'); ``` This event allows you to accurately link customer data when they log in to your web app giving you more precise data analysis. For more details, check out the [recording events doc](/data-collection/recording-events#using-identify-providers). ## Introducing the Pipedrive integration *June 24th, 2025* With the new Pipedrive integration, you can embed Pipedrive forms directly into your content items.  This means you keep your content and related Pipedrive forms in one place. Just enter the matching Pipedrive form URL to link the form you need. Check out the [Pipedrive integration doc](/integrations/pipedrive) for more details. ## New PATCH mutation endpoint in public beta *June 24th, 2025* We’ve introduced a new `PATCH` endpoint for content items in the Mutation API, allowing you to update just a single field in an existing item instead of replacing the whole object. This aligns with HTTP PATCH best practices for partial updates and efficiency. Plus, thanks to refined metadata handling, this endpoint won’t trigger the `changed_on` timestamp — so batch updates no longer clutter the editor interface. For more details, check out the [Mutation API doc](/mutation-api/content-items-create-update-and-destroy#patch-a-content-item). ## Introducing the Dealfront (Leadfeeder) integration *June 18th, 2025* We’re excited to introduce a new B2B integration in Prepr with Dealfront. This powerful new integration lets you segment website visitors based on their industry and company size.  This allows you to personalize content for an enhanced user experience for your B2B audience. For more details, check out the [Dealfront integration guide](/integrations/dealfront). ## New enumeration JSON editor *June 11th, 2025* We've introduced a new option to add or edit enumeration values using a JSON editor.  This new option enables you to quickly access and copy the data structure and add your own updated JSON. This saves time, especially when you need to add or edit an enumeration with an large list of values. Check out the [enumerations doc](/content-modeling/managing-enumerations) for more details. ## Personalization across all Stack fields *June 3rd, 2025* Previously, you could add personalization and A/B test content only to a stack field directly included in the model. We've enhanced the *Stack* field to allow personalization and A/B test content at any level in the content structure. These include stack fields in components and within dynamic content fields. For example: In a CTA button component to only personalize the button instead of the whole section of the content item where it's used.  This feature gives you more flexibility for adaptive content in the web app and an improved user experience. To use this feature, make sure to use the newest [GraphQL API version 2025-05-27](/graphql-api/upgrade-guide#version-2025-05-27). ## Dynamic content in components *June 3rd, 2025* Previously, you could only add a dynamic content field to a model. It's now possible to add a *Dynamic content* field to a component to add rich content sections to your section-based pages. For example, to publish a guide with your chosen styling.  This feature allows more flexibility when editing content and more dynamic content delivery in the web app. To use this feature, make sure to use the newest [GraphQL API version 2025-05-27](/graphql-api/upgrade-guide#version-2025-05-27). ## New GraphQL API version 2025-05-27 is available *May 27th, 2025* Our newest GraphQL API version brings you more flexibility when creating a schema and developing an adaptive web app with the following new features: - Support for A/B tests and adaptive content elements within *Stack* fields in components, allowing for more dynamic content delivery and an improved user experience. - The *Dynamic Content Editor* field is now available in components, enabling you to create engaging and personalized content easily. - We’ve introduced the *Tags* field in components, providing a flexible way to categorize and manage your content more effectively. - You can now access a default query to retrieve the locales available in your environment, making it easier for you to implement localization in your front end. - We've enhanced sorting on `string` fields to be case-insensitive, ensuring a more intuitive and user-friendly experience. Check out the [GraphQL API upgrade guide](/graphql-api/upgrade-guide#version-2025-05-27) for more details. ## Setting an initial value for *Stack* field *May 13th, 2025* It's now possible to add elements such as specific content items and components to the initial value of a *Stack* field. This release also allows you to add an initial value to a [*Content reference* field](/content-modeling/field-types#content-reference-field). With this feature, you get a suggested outline when you create more complex content items such as pages with many possible elements. For example, when you create a new *Page* content item, you could get a preselected *Hero* component, *Feature* component and a *Call to action* item.  This allows you to create consistent and structured content, and saves you time and reduces errors. Check out the [*Stack* field setup](/content-modeling/field-types#stack-field) for the setup details. ## Improved content item filtering *May 13th, 2025* We've added the **Unpublished changes** option to the *Publication status* filter. This addition joins the existing filters for *Published*, *Scheduled*, and *Not published* items, giving you better control and visibility over draft updates. You can use this filter option in the list, calendar, and kanban views to streamline your content management workflow. Check out the [content management doc](/content-management/managing-content/managing-content-items#publication-status) for more details. ## Support for dates and location fields in Algolia and Typesense integrations *May 8th, 2025* The Prepr search integrations with Algolia and Typesense now support date fields and location fields. This update enables more flexible filtering options, such as showing nearby events or sorting content based on dates, making the integration more useful for time-based and location-based use cases. Check out the [Algolia docs](/integrations/algolia) and [Typesense docs](/integrations/typesense) for setting up the integration with dates and location fields. ## Two-factor authentication (2FA) required for Owners and Admins starting July 1, 2025 *May 8th, 2025* To strengthen account security, 2FA will be required for all users with an *Owner* or *Admin* role in a paid Prepr organization as of July 1, 2025. If 2FA is not enabled by that date, users will be prompted to set it up before accessing Prepr. SSO users are exempt from this requirement. Check out the [Activating two-factor authentication](/project-setup/managing-users#activate-two-factor-authentication) guide for more details. ## Improved document naming and URL structure *May 6th, 2025* We're pleased to let you know that we've improved how document files are named and how their URLs are set in Prepr CMS. Now when you upload new documents (pdf, zip, docx and xlsx), they retain their original file name. The URL to download a document includes a cleaner prefix after the hostname, providing a more structured and consistent format for better organization and readability. **Example** Previous URL structure: `https://example.files.prepr.io/695a4d1eiaom-sustainability-report.pdf` New URL structure: `https://example.files.prepr.io/695a4d1eiaom/sustainability-report.pdf` These changes make it easier for you to manage these assets, better visibility, and they align with SEO best practices. Check out the [Editing assets doc](/content-management/managing-assets/managing-assets#editing-assets) for more details on documents fields. ## Sending events to Google Tag Manager *May 1st, 2025* It's now possible to send experiment-related Prepr events to Google Tag Manager (GTM). This is a seamless integration of Prepr's experiment data with your existing GTM setup, giving you centralized tracking. To enable the integration to GTM, simply update the *Prepr Tracking Code* in your front end to include the *googleTagManager* destination flag. Check out the [tracking setup doc](/data-collection/setting-up-the-tracking-code#sending-events-to-google-tag-manager-gtm) for more details. ## Introducing content item calendar view *May 1st, 2025* With the content item calendar view, you can now easily manage your scheduled content directly within a calendar interface. With this clear, visual overview of all your scheduled items, it's now easier to manage timing and avoid overlaps saving time and keeping you organized.  For more details, check out the [content management doc](/content-management/managing-content/managing-content-items#calendar) ## Publication status in content item list *April 18th, 2025* We’ve updated the content item list display for content reference fields, stack fields and their corresponding search dialogs to display the publication status instead of the workflow stage. Now when you view these fields or add a content item for a content reference or stack field, you can easily see which of the listed content items are published or not.   This change helps reduce confusion, and gives you clearer and more actionable information. Check out the [content management docs](/content-management/managing-content/managing-content-items#publication-status) for more details on the publication status. ## Setting a personal default locale *April 17th, 2025* Users can now set a personal default locale that overrides the environment’s default. This is especially useful for international teams, giving editors a more tailored experience when working with multilingual content.  Check out the [localizing content docs](/content-management/localizing-content#working-with-multiple-locales) for more details. ## New slug option to remove trailing slash automatically *April 11th, 2025* We’ve added a new option to automatically remove trailing slashes from slugs when the field loses focus. A trailing slash typically indicates a directory in URLs, but inconsistent use can lead to messy or duplicate links. With this update, Prepr ensures cleaner and more consistent URLs by trimming trailing slashes, helping you maintain a more structured and SEO-friendly content setup.  Check out the [slug field settings](/content-modeling/field-types#slug-field) for more details. ## Introducing the new *Form* field *April 8th, 2025* With the new *Form* field, you can now easily add *HubSpot* and *Typeform* forms directly in your content items.  With this feature, you keep your content and related embedded forms all in one place. Just click to search for the form you need. It's that simple. Check out the integration docs for [HubSpot](/integrations/hubspot#make-hubspot-forms-available-in-content-items) and the [Typeform](/integrations/typeform#add-form-field-to-schema) to learn how to use the [Form field](/content-modeling/field-types#form-field). ## Advanced filtering on content items *April 8th, 2025* We bring you more advanced filtering on content items to help you find exactly the content items you need. Until now, you could only filter by one value for each of the listed filter options, apart from *Tags*. With this update you can filter by multiple values, for example when you want to view a list of both *Page* and *Post* content items, you can simply choose both values when you filter by the *Model* option.  This update ensures efficient content searches. Check out the [content management docs](/content-management/managing-content/managing-content-items#filter-content-items) for more details on content filters. ## Help text as field value placeholder *April 7th, 2025* In addition to the help text line above a field or as a tooltip next to a field name, we've added a new way to display help texts: directly in the field value as a placeholder. Now, you can see some help text directly in the *Text*, *Slug*, *Tags*, *Number*, *Location*, and *Social* fields.  This gives you clear instructions while keeping the interface clean and intuitive. With this update, editor guidance is always in the right place without cluttering the design. Check out the setup details in the [field appearance settings](/content-modeling/field-types#basic-field-settings). ## New Help text field for better editor guidance *April 2nd, 2025* We're happy to bring you improved guidance while editing content with the new *Help text* field. A developer can add this field to any model or component to give you more visible and structured instructions.  With the flexibility of this feature, it ensures smoother and more efficient content management. For more details, check out the [Help text field setup](/content-modeling/field-types#help-text-field). ## Removal of after and before parameters in REST Mutation API index requests *March 28th, 2025* We’re simplifying our REST Mutation API pagination parameters. Starting **July 1, 2025**, the following changes will take effect in all index requests: - The `after` and `before` response parameters will be removed. - The `after` request parameter (used to skip pagination items) will also be removed. If you’re currently using the `after/before` parameters, we recommend updating your integration to use the `skip` parameter instead. This update improves consistency across our APIs. ## Introducing conditional fields *March 27th, 2025* Introducing conditional fields - a huge step toward easier and more efficient content management. With conditional fields you can now choose to show or hide fields or sections depending on another field's value.  This feature simplifies the editing experience with a cleaner interface without unnecessary fields. For example, to show either the external URL field or an internal link field in the content item and not both.  Check out the [field settings doc](/content-modeling/field-types#basic-field-settings) for more details. ## New in Visual Editing: Segment & A/B Test preview *March 25th, 2025* We've enhanced [Visual Editing](/changelog#introducing-visual-editing) with new *Segment* and *A/B test* variant switches. These switches allow you to preview personalized content for specific segments and each A/B test variant before publishing the content item. By previewing content for specific groups of targeted visitors, you have more control and confidence in your content adjustments.  The *Segment* and *A/B test* switches are available automatically if your front end uses the [latest Prepr Next.js package](/prepr-nextjs-package). If not, check out the [setup details](/project-setup/setting-up-visual-editing#enable-segment-and-ab-test-switches) to enable the adaptive preview for any other front-end framework. ## Managing content with shortcut keys *March 17th, 2025* In line with the [*Content UX* improvements](#updated-content-item-ux) released last week, we're happy to introduce new shortcut keys to help you manage your content faster and more efficiently. Now, with just a couple of keystrokes, you can quickly select all content items with , add an item with , publish a content item with , and more - giving you greater control and saving you valuable time. For more details, check out the [managing content items docs](/content-management/managing-content/managing-content-items#manage-content-items-with-shortcut-keys). ## Improved rescheduling of content items *March 13th, 2025* Based on your feedback on the [recent Content UX updates](#updated-content-item-ux), we've improved how rescheduling works for published content — it now updates the *First Published at* date and time to the new date and time you choose when you reschedule the content item.  By rescheduling a published content item, you can choose how to order the content items in the front end when they're ordered by the *First Published at* date and time. This gives you more flexibility and allows you better control over the order of published content. Check out the [content management docs](/content-management/managing-content/managing-content-items#schedule-a-content-item) for more details. ## Introducing Visual Editing *March 11th, 2025* Visual Editing is finally here! This new feature allows you to view content changes to your web pages in real-time with a convenient side-by-side view in the Prepr Content page.  This means, you can instantly see how your edits affect the page layout and content, reducing the need to switch between tabs to check your updates. Visual Editing gives you instant, crystal-clear insight into your changes, making your editing process a lot faster, effortlessly smooth, and a great deal more intuitive. Check out the [visual editing setup](/project-setup/setting-up-visual-editing) and the [content management docs](/content-management/managing-content/managing-content-items) for more details. ## Improved UX for content references *March 11th, 2025* In response to your feedback, we've improved the UX for content references when editing a content item.  With the updated overlays, now you always know where you are in deeply nested items. Together with a cleaner interface, this clarity minimizes errors and gives you full control over your content, making content updates seamless and stress-free. Check out the [content reference doc](/content-management/managing-content/creating-rich-content#adding-content-references) for more details. ## Updated content item UX *March 11th, 2025* To support the *Visual Editing* feature, we've updated the *Content Item* detail page with a cleaner, more intuitive interface. Primary content editing actions have been moved to the top. You'll also notice that the default publish action has been updated to match your preference.  We trust this update gives you a more streamlined experience when editing content. Check out the [content management docs](/content-management/managing-content/managing-content-items) for more details. ## Deploying to Vercel directly from Prepr *March 10th, 2025* As you've requested, you can now deploy your website directly from Prepr. Simply click the new **Build and deploy** button to deploy your website to Vercel and the live website is updated with your latest published content as soon as you need it.  This new feature is especially useful for statically built and deployed websites where you don't see your content changes immediately after publishing. This way, you have more control over the website content without needing to switch over to Vercel or to contact developers to trigger a new deployment for you. Check out the [Vercel integration doc](/integrations/vercel) for the setup details. ## Improved video upload feedback *March 5th, 2025* We've improved the video upload experience in Prepr by adding a real-time progress indicator, showing the exact percentage of transcoding completion. This makes it easier to track the status of larger video uploads. Additionally, we've introduced a `Failed to Transcode` error message, providing clear feedback if an issue occurs during processing. Check out the [assets doc](/content-management/managing-assets/managing-assets#uploading-assets) for more details. ## Improved content item creation *March 3rd, 2025* Based on your feedback on adding content items, we've refined the **Add item** action for usability. Previously, when adding an item, you could select from all models when creating new content items. From now on, the model selection window excludes single-item models if their content item has been created. This update declutters the model selection, making content management more intuitive and efficient. Check out the [content management](/content-management/managing-content/managing-content-items#create-a-content-item) doc for more details. ## Setting an image focal point *February 26th, 2025* As requested, we’ve added a feature that allows you to set a focal point when adding or editing an image in a content item.  To enable the option to set an image focal point instead of the option to crop the image, check out the [asset field settings](/content-modeling/field-types#assets-field-settings) for more details. By setting a focal point for an image, you ensure the key parts of the image remains visible (such as a person’s face or a product), even when resized for different screen sizes. This feature means your front end delivers better visual presentation, and improves user experience. Check out the [image docs](/content-management/managing-assets/editing-and-configuring-assets#setting-an-image-focal-point) for more details. ## New Marketer role *February 24th, 2025* With the new *Marketer* role, you can add your marketing team members to Prepr. The Marketer role is designed for users who manage and optimize audience segmentation within Prepr. This role has the same permissions as the existing *Editor* role, allowing users to create, edit, and manage content. However, marketers also have access to the **Segments** feature, enabling them to define and view audience segments. Check out the [roles and permissions doc](/project-setup/managing-roles-and-permissions) for more details. ## Introducing the Zapier integration *February 19th, 2025* We set up Prepr’s Zapier integration as part of our efforts to continually improve your experience with integrating to Prepr CMS. This new integration enables automated tagging of customer profiles and provides an external trigger for event tracking in Prepr. With Zapier you can choose any listed app to send data to Prepr automatically.  Think about the case where you want to add a tag with the `industry` of a known customer in Prepr when they request a demo through a HubSpot form. Previously, you had to manually export and import this data to Prepr or create a custom API integration. Now you can easily automate this process with [Zapier](https://zapier.com/apps/prepr/integrations) by simply choosing the listed app to pair such as **HubSpot**, a trigger like a **New Form Submission** (for example, when there's a demo request), and the Prepr action of **Tag a Customer Profile**. This workflow in Zapier automatically triggers Prepr to save the customer data you choose in the tag of a known customer profile. This means you have an easy, automated segmentation setup without development effort, leading to better personalization. Check out the [Zapier integrations doc](/integrations/zapier) for more details. ## Introducing support for semantic versioning (SemVer) *February 11th, 2025* As requested we've added support for semantic versioning in the *HTTP header* context in segments. This means you can create conditions like in the example image below.  Semantic versioning gives you more flexibility and precision with your segmentation in the HTTP header context. You can confidently enforce version requirements, preventing unwanted or inconsistent content when segmenting your customers. Check out the [segments doc](/personalization/managing-segments#http-header) for more details. ## Bulk publishing content items *February 11th, 2025* We’re very happy to bring you new options to quickly publish or unpublish multiple items simultaneously. With these new actions you can choose to publish or unpublish your chosen content items immediately or to schedule these actions for a future date.  These new features help you efficiently release and manage batches of content items, such as campaigns or updates that span several pieces of content, saving time and reducing manual effort. No more repetitive manual tasks means that you can manage your content faster, freeing up time to focus on strategy and creativity. Check out the [managing content docs](/content-management/managing-content/managing-content-items#bulk-actions-on-content-items) for more details. ## Introducing the Prepr Next.js package *February 5th, 2025* We’re excited to introduce the **Prepr Next.js package**, a powerful toolkit to streamline your personalization and A/B testing implementation. Now you can integrate Prepr’s features into your Next.js front end faster and more efficiently with the following features: - It provides API request headers for the following values: - Each visitor's customer ID. You need this API request header, `Prepr-Customer-Id`, when you query adaptive content and content with A/B testing. - Any UTM parameters, if applicable. This is useful to identify customers who enter your website through a social media campaign, for example. - HubSpot cookie, if it exists. This is useful for identifying customers who are tracked in HubSpot as a lead, for example. - The visitor's IP address. This is useful for localization. * The *Adaptive Preview Bar*. When you include this component in your front end, you allow content editors to effortlessly toggle between A/B test variants and personalized experiences for validation.  Check out the [Prepr Next.js package guide](/prepr-nextjs-package) or visit the [GitHub repository](https://github.com/preprio/prepr-nextjs) directly for the step-by-step instructions to install and use the package. ## Tracking customers by their email address *February 5th, 2025* You can now track a visitor's email address and store it in their customer profile in Prepr. You can do this by triggering a simple javascript in your front end when the customer provides their email address in the web app. ```js copy prepr('event', 'Email', 'jesse.ward@acme-company.com'); ``` Check out the [tracking events doc](/data-collection/recording-events#Email) for more details. This feature makes it easier to track customer interactions in other platforms you might be using, enabling more insights. ## Improved *Publication date* filter for the content item list *January 15th, 2025* We're happy to bring you an improved publication date filter when you view the content items list. The previously called *Published on* filter is now called *Publication date* for greater clarity. This filter is based on the content item *Publication date* instead of the previous *Publish on* dates. We've also updated the date selection for this filter to support future dates, allowing you to easily find not only past published content items, but also scheduled content items.  For more details on filtering content items, check out the [managing content doc](/content-management/managing-content/managing-content-items#filter-content-items). ## New info text to indicate null boolean values *January 14th, 2025* We've added info text to indicate when a boolean value is null in a content item. This info text indicates that you need to explicitly set a value for this field and save the content item.  ## Sync your schema with Azure DevOps *January 13th, 2025* We're happy to announce that we've added another option to the *Schema sync* feature in Prepr. You can now choose to sync a schema using *Azure DevOps*. If your preferred tool for CI/CD workflows and source control management is *Azure DevOps*, you can include the sync process to manage schema updates in this single platform.  Check out the step-by-step guide in the [Azure DevOps schema sync doc](/development/working-with-cicd/syncing-a-schema#azure-devops-schema-sync). ## Support for Stories in the REST API has been fully removed *January 13th, 2025* Following the deprecation of Stories in Prepr UI in January 2024, we have now completed the removal process by eliminating all related functionality from our REST API. We trust that this update has very limited impact, if at all, but please ensure your integrations are updated, if needed. Contact Prepr support if you have any questions. ## Duplicate models, components and enumerations instantly *January 7th, 2025* We're happy to bring you yet another feature you've requested - The option to duplicate models, components, and enumerations.  Quickly create similar models, components or enumerations without the need to manually add each field. This saves you time and reduces errors by duplicating existing structures, streamlining your workflow for faster content modeling and delivery. For more details, check out the [content modeling docs](/content-modeling/managing-models#duplicate-a-model). ## Improved image naming and URL structure *January 6th, 2025* We're pleased to let you know that we've improved how image files are named and how their URLs are set in Prepr CMS. Now when you upload new images, they retain their original file name. The optimized URL for each image also includes a cleaner prefix after the hostname, providing a more structured and consistent format for better organization and readability. **Example** Previous URL structure: `https://example.stream.prepr.io/{format_options}/695a4d1eiaom-sustainability.png` New URL structure: `https://example.stream.prepr.io/695a4d1eiaom/{format_options}/sustainability.png` These changes make it easier for you to manage these assets, better visibility, and they align with SEO best practices. Check out the [Editing assets doc](/content-management/managing-assets/managing-assets#editing-assets) for more details on image fields. Source: https://docs.prepr.io/changelog --- # Prepr's product roadmap We’re constantly improving our products, integrations, and services. Learn about features we're working on and upcoming improvements. ## Q4 2025 ### Improve CRM/CDP-integrations for segmenting We are enhancing CRM/CDP integrations to streamline the use of external audience segments for adaptive content delivery. This update will enable seamless integration with external CRM/CDP platforms, allowing you to leverage existing segments - such as those created for specific campaigns or based on leads - directly within your website. By utilizing these segments, you can deliver highly targeted, adaptive content to enhance engagement and personalization strategies, ensuring a more impactful and relevant user experience. ### Publish nested items To prevent broken or incomplete sites due to unpublished linked content, we are introducing the *Publish Nested Content Items* feature in Prepr CMS. This allows editors to publish a content item along with its related (child) items in a single action, ensuring all dependencies are live simultaneously. ### AI-generated variants for experiments With this feature you can request AI to make suggestions for A/B/n test or personalized variants to improve your experiments. This allows you to quickly and effortlessly produce diverse content for personalized experiences and A/B/n tests. ### Content trees To enhance visibility into content dependencies, we are introducing *Content Trees*. This feature provides a hierarchical tree view of specific models, allowing content marketers to easily understand and navigate content relationships. By visually mapping parent-child dependencies, editors gain better insights into how content items are structured and interconnected. ### Automatic redirects on slug changes To prevent broken links and ensure a smooth user experience, we’re introducing automatic redirects when a slug is manually changed in a content item. This means editors no longer need to manually create redirects—visitors will always be guided to the correct page. ### Redesigned role & permission management We will rework role management in Prepr to give you more granular control over content permissions. Instead of broad roles, permissions are now defined around clear actions — Create, Read, Edit, Delete, Publish, and Unpublish — with the ability to apply filters on models, locales, and workflow stages. Special permissions such as commenting, *Assigned to me* and member-based restrictions add further flexibility. ### Expanded A/B/n testing We're enhancing A/B testing to include more than two variants (A vs. B) when running these tests on specific text fields or the stack field. A/B/n testing allows you to run more effective experiments by enabling the direct comparison of multiple designs, headlines, or user flows in a single experiment. ## Q1 2026 ### Improvements on content item comments section The upcoming improvements to the commenting option, designed to provide more precise and collaborative feedback capabilities. This update will introduce field-level commenting, allowing users to leave comments on specific fields rather than entire content items. Additionally, comments will support locale segregation, user assignment, threaded replies, and resolution tracking. These enhancements aim to streamline feedback workflows, foster better collaboration across teams. ### Select A/B test winner automatically Automatically select the winning variant after a predefined number of impressions or when a confidence threshold is reached. This ensures A/B tests conclude efficiently and top-performing variants are applied without manual review. ### Enhanced ‘Ask AI’ with custom and inline prompts Introduce an ‘AI Optimize’ option in Dynamic Content Fields, allowing users to refine or improve content automatically. Expand the existing ‘Ask AI’ functionality with custom prompts and inline prompting, enabling more flexible and context-aware AI assistance directly within the editor. ### AI-powered schema suggestions and templates To streamline the schema design process, Prepr will introduce AI-generated suggestions and ready-to-use schema templates. This feature will help users create efficient, consistent content models more quickly by recommending fields, structures, and best practices based on content type and use case. ### AI-generated image alt texts, titles and descriptions We’re introducing automated image alt text generation to simplify WCAG compliance and improve accessibility. With the new Image processing integration, Prepr can now automatically process images on upload using AI to generate titles, descriptions, and alt texts. This ensures your media library is enriched with consistent, SEO-friendly metadata — without extra manual work. Source: https://docs.prepr.io/roadmap --- # Setting up your production-ready project *Welcome to Prepr, a data-driven headless CMS with a built-in personalization engine and optimization features. Learn about the different parts that you need to set up your project with Prepr and the steps to follow to make the best use out of its features for your front-end applications.* If you can't wait to dive straight into Prepr, follow the [Quick start guide](/quick-start-guide) to get your feet wet. Learn more about the structure of your Prepr project and then move on to the step-by-step guide to set it up. Looking for something specific? Check out the detailed resources below. Source: https://docs.prepr.io/project-setup --- # Content modeling *Explore the resources below to get started with content modeling and learn how to set up a well-defined schema in Prepr CMS.* Before diving into Prepr, learn the basics about content modeling and how to model content using some typical examples like a *Blog*, *Page* and *Personalization*. Dive into Prepr and learn how to set up a schema by managing models, components, setting up remote sources and other more advanced features. Source: https://docs.prepr.io/content-modeling --- # Connecting a front-end framework The flexibility of a data-driven headless CMS allows you to connect your favorite front-end framework, deliver content and optimize and personalize the customer experience. Source: https://docs.prepr.io/connecting-a-front-end-framework --- # Developing with Prepr CMS *Discover everything you need to know to develop with Prepr CMS, including resources for connecting front-end frameworks, best practices, managing CI/CD pipelines and integration guides.* Source: https://docs.prepr.io/development --- # Content management Discover all you need to know about managing content items, how to handle assets, localizing content, and collaboration when working with content items in Prepr CMS. Source: https://docs.prepr.io/content-management --- # Data collection *Prepr CMS offers several data-driven features such as Adaptive content, A/B testing, and Recommendations. To power these features, Prepr requires customer data. This data is essential for creating segments for personalization, evaluating A/B test results, and determining relevant recommendations. Discover all you need to know about collecting and managing customer data to make the most out of these features.* Learn more about data collection key concepts and move on to the step-by-step guide to set it up. Looking for something specific? Check out the detailed resources below. Source: https://docs.prepr.io/data-collection --- # Personalization *Discover all you need to know about making your website adaptive by setting up personalization, managing segments and creating adaptive content to improve engagement and user experience.* Source: https://docs.prepr.io/personalization --- # A/B testing *Discover all you need to know about setting up and using Prepr CMS A/B testing to improve engagement and user experience.* Source: https://docs.prepr.io/ab-testing --- # Setting up recommendations Estimated duration: 15-30 minutes ## Introduction Prepr allows you to add recommendations to your web application quickly. This tutorial demonstrates how to deliver recommendations using the Prepr GraphQL API. Follow the step-by-step guide below. ## Use case Deliver highly relevant content recommendations to the visitors of your websites and apps using the GraphQL API to increase engagement. Let's examine an everyday use case: an article that you want to show recommendations for. Recommendations are usually displayed below an article to entice visitors to view more content. With Prepr, you can display three types of recommendations: - Similar items - People also viewed items - Popular items ### Similar items Similar items are recommendations similar to the article the visitor is currently viewing. Because it's on the same topic, or because it's by the same author, or maybe it's approximately the same length. With this recommendation type, the algorithm looks at the characteristics of the article (content, meta-data, links to other articles, etc.) and determines what the most relevant related articles are based on a score. ### People also viewed items People also viewed items are items that other visitors also viewed along with the item that a visitor is currently viewing. The algorithm looks at the current item and determines the visitors that viewed this item. It then lists the other items that these visitors also viewed. ### Popular items Popular items, the name says it all, are the most viewed items. The algorithm looks at how often an item has been viewed for this recommendation type. You could say this is not a recommendation but sorting by popularity. ### Content structure Before you start generating the recommendations, it’s a good idea to look at the content model of the article. That structure largely determines how accurate the recommendations become.  In this case you have an article with a number of content fields: title, intro and content. In addition, there are references to an author and to one or more categories. And finally, an editor can manually add tags. Prepr uses all this information to provide the most relevant recommendations. ## Creating a Prepr CMS account Following this guide requires a (free) Prepr CMS account. - Go to https://signup.prepr.io/ and sign up - Follow the [quick start guide](/quick-start-guide) to add models and content items ## Querying the API for similar items To retrieve similar items, you must first have the ID of the content item where you want to show recommendations for ### Getting a content item ID - Go to the **Content** tab and open the content item for which you want to retrieve similar items. - Click the icon and choose the **Copy item ID** option.  ### Retrieving similar items - Click the icon and choose the **Access tokens** option. - Click to open the *GraphQL Production* token details. - Click the **Open in API explorer** link.  View the API reference for all [API authentication details](/graphql-api/authorization) - Add the following query to the explorer: ```graphql copy query { Similar_Articles( id: "0cbe2455-124c-4820-b2ac-dcc4261e150c" ) { items { _id title } } } ``` - Replace the **id** value with the ID of your content item Note the **Similar\_Articles** query type at the beginning of the query. For each content model in your environment the Prepr creates a corresponding GraphQL type with a similarity algorithm. The plural type name of the content model is prefixed with Similar\_. For example Article generates a type Similar\_Articles. You can find all these options in the API Explorer. - Run the query The result should look something like: ```json copy { "data": { "Similar_Articles": { "items": [ { "_id": "885b71ac-5a4b-4d2e-9770-a4a6f20425e9", "title": "15 Tips On How To Brand Yourself Online" }, { "_id": "f1d9b142-883f-4964-8d8f-cd2f255330a2", "title": "Why Customization Is Key For Entrepreneurs In The Digital Age" }, { "_id": "dd42b8c4-4773-4fdd-a71f-87e57b35beaa", "title": "Building User Trust In UX Design" }, { "_id": "79c453ed-ffe2-4aec-8fb2-f549e3775264", "title": "Building A Video Streaming App With Nuxt.js" }, { "_id": "5a53b271-898e-4eef-b877-5863b34b6ff9", "title": "UI Design Testing Tools I Use All The Time" }, { "_id": "ca0e0d37-600b-42f7-a013-9b0f8e18f127", "title": "The Evolution Of Jamstack" }, { "_id": "dd3309eb-df84-4e4b-8fdf-80b31b8eb58a", "title": "The Rise Of Design Thinking As A Problem Solving Strategy" }, { "_id": "f4b65d11-c2e2-4320-a363-e7d420d03ed2", "title": "Modeling A GraphQL API For Your Blog" } ] } } } ``` That's all. You now have recommendations that you can show in your application. Let's see how we can improve the recommendations even more. ### Filtering the result The previous example included all items for determining recommendations. But often, you want to make the result even more accurate. For example, you may want to query only recommended articles published recently or in a particular category. So let's see how you can do that. - Expand the query with the following parameters: ```graphql copy query { Similar_Articles( id: "0cbe2455-124c-4820-b2ac-dcc4261e150c" where: { _publish_on_gt: "2021-01-01T00:00:00+00:00" categories: { _slug_any: [ "ux-design", "development" ] } }, limit: 3 ) { items { _id title } } } ``` - We added **\_publish\_on\_gt**: "2021-01-01T00:00:00+00:00" to show only articles published after January 1, 2021. Note the underscore at the beginning of the parameter. - We added categories: **`{ _slug_any: [ "ux-design", "development" ] }`** to limit the result to only articles in the “UX Design” or the “Development” categories. Note the square brackets because we’re dealing with an array. - We added **limit: 3** to limit the number of results to three items The result should look something like: ```json copy { "data": { "Similar_Articles": { "items": [ { "_id": "dd42b8c4-4773-4fdd-a71f-87e57b35beaa", "title": "Building User Trust In UX Design" }, { "_id": "5a53b271-898e-4eef-b877-5863b34b6ff9", "title": "UI Design Testing Tools I Use All The Time" }, { "_id": "dd3309eb-df84-4e4b-8fdf-80b31b8eb58a", "title": "The Rise Of Design Thinking As A Problem Solving Strategy" } ] } } } ``` View the API reference for [all filter options](/graphql-api/fetching-filtering-collections). ### Optimizing the recommendation algorithm You can tweak the recommendation algorithm further if you want more control over the results. Prepr uses three parameters to determine recommendations: Entities, Tags, and References. - **Entities** - Prepr uses AI Text Analysis to determine what an article is about by automatically extracting entities from the text. - **Tags** - Prepr uses the tags associated with an article. - **References** - Prepr uses an item's relationship with other content items. So in this example, Prepr looks at other articles in the same category and articles by the same author. By default, Prepr uses all three parameters to determine recommendations, but you can change that and specify the weight of each parameter. Here’s an example of how that works: ```graphql copy query { Similar_Articles( id: "0cbe2455-124c-4820-b2ac-dcc4261e150c" where: { _publish_on_gt: "2021-01-01T00:00:00+00:00" categories: { _slug_any: [ "ux-design", "development" ] } }, limit: 3 rules: { entities: 1 tags: 0 references: 0.5 } ) { items { _id title } } } ``` - We added rules: **`{ entities: 1, tags: 0, references: 0.5 }`** to indicate that tags should not be included and that references count for half. Note that the commas are optional. We recommend starting with the default setting and adding rules only if the result does not meet your expectations. View the [API reference](/graphql-api/personalization-recommedations-similar-content) for all rules options. ## Querying the API for People Also Viewed items To retrieve *People also viewed* items, you need the ID of the content item that you want to show recommendations for. ### Getting a content item ID - Go to the **Content** tab and open the content item you want to use as the reference. - Click the icon and choose the **Copy item ID** option.  Now that you have the *Content Item ID*, you can track visitors who viewed the same content item. That information can be used to display the *People Also Viewed* items. ### Capturing views You can capture view events in Prepr using a lightweight piece of JavaScript, the *Prepr Tracking Code*. Follow the steps in the [Tracking setup guide](data-collection/setting-up-the-tracking-code#enabling-prepr-tracking) to add the *Prepr Tracking Code*. Once you've enabled tracking, you can then [add a meta tag](/data-collection/recording-events#tracking-content-items) to record view events on content items. Check out the [Events doc](/data-collection/recording-events) for all tracking options. ### Retrieving People also viewed items Now that you’re tracking the visitors that view an item, you can retrieve the other items that these visitors also viewed. - Click the icon and choose the **Access tokens** option to view all the access token. - Click to open the *GraphQL Production* token details. - Click the **Open in API explorer** link.  View the API reference for all [API authentication details](/graphql-api/authorization) - Add the following query to the explorer: ```graphql copy query { PeopleAlsoViewed_Articles ( id : "90276002-d628-4ba6-b3c8-f756c486b67b" ) { items { _id, title } } } ``` Note the **PeopleAlsoViewed\_Articles** query type at the beginning of the query. Prepr automatically provides you with a `PeopleAlsoViewed` query for each model. For example, if your model name is Article, you also get the PeopleAlsoViewed\_Articles query. You can find all these query options in the API Explorer. The result should look something like this: ```json copy { "data": { "PeopleAlsoViewed_Articles": { "items": [ { "_id": "0cbe2455-124c-4820-b2ac-dcc4261e150c", "title": "How to set up a Google Ads account" }, { "_id": "dd42b8c4-4773-4fdd-a71f-87e57b35beaa", "title": "Building User Trust In UX Design" }, { "_id": "79c453ed-ffe2-4aec-8fb2-f549e3775264", "title": "Building A Video Streaming App With Nuxt.js" }, { "_id": "5a53b271-898e-4eef-b877-5863b34b6ff9", "title": "UI Design Testing Tools I Use All The Time" }, { "_id": "dd3309eb-df84-4e4b-8fdf-80b31b8eb58a", "title": "The Rise Of Design Thinking As A Problem Solving Strategy" }, { "_id": "f1d9b142-883f-4964-8d8f-cd2f255330a2", "title": "Why Customization Is Key For Entrepreneurs In The Digital Age" }, { "_id": "885b71ac-5a4b-4d2e-9770-a4a6f20425e9", "title": "15 Tips On How To Brand Yourself Online" }, { "_id": "ca0e0d37-600b-42f7-a013-9b0f8e18f127", "title": "The Evolution Of Jamstack" }, { "_id": "f4b65d11-c2e2-4320-a363-e7d420d03ed2", "title": "Modeling A GraphQL API For Your Blog" } ] } } } ``` ### Filtering the result The previous example includes all items that other users viewed. But often, you want to make the result even more accurate. For example, only show items published recently or in a particular category. So let's see how you can do that. - Expand the query with the following parameters: ```graphql copy query { PeopleAlsoViewed_Articles( id : "90276002-d628-4ba6-b3c8-f756c486b67b", where: { _publish_on_gt: "2021-01-01T00:00:00+00:00" categories: { _slug_any: [ "ux-design", "development" ] } }, limit: 3 ){ items { _id title } } } ``` - We added `_publish_on_gt: "2021-01-01T00:00:00+00:00"` to show only articles published after January 1, 2021. Note the underscore at the beginning of the parameter. - We added categories: `{ _slug_any: [ "ux-design", "development" ] }` to limit the result to only articles in the “UX Design” or the “Development” categories. Note the square brackets because you’re dealing with an array. - We added `limit: 3` to limit the number of results to three items. Result: ```json copy { "data": { "PeopleAlsoViewed_Articles": { "items": [ { "_id": "dd42b8c4-4773-4fdd-a71f-87e57b35beaa", "title": "Building User Trust In UX Design" }, { "_id": "79c453ed-ffe2-4aec-8fb2-f549e3775264", "title": "Building A Video Streaming App With Nuxt.js" }, { "_id": "5a53b271-898e-4eef-b877-5863b34b6ff9", "title": "UI Design Testing Tools I Use All The Time" } ] } } } ``` ## Querying the API for most popular items To show the most popular items, you must track how often visitors view content items. That information can be used to display the most popular items. ### Capturing views You can capture view events in Prepr using a lightweight piece of JavaScript, the *Prepr Tracking Code*. Follow the steps in the [Tracking setup guide](data-collection/setting-up-the-tracking-code#enabling-prepr-tracking) to add the *Prepr Tracking Code*. Once you've enabled tracking, you can then [add a meta tag](/data-collection/recording-events#tracking-content-items) to record view events on content items. Check out the [Events doc](/data-collection/recording-events) for all tracking options. ### Retrieving most popular items Now that you’re tracking how often visitors view an item, you can retrieve the most popular items. - Click the icon and choose the **Access tokens** option. - Click to open the *GraphQL Production* token details. - Click the **Open in API Explorer** link.  View the API reference for all [API authentication details](/graphql-api/authorization) - Add the following query to the explorer: ```graphql copy query { Popular_Articles { items { _id title _views } } } ``` Note the **Popular\_Articles** query type at the beginning of the query. Prepr automatically provides you with a popularity query for each model. If your model name is Article, you also get the Popular\_Articles query. You can find all these query options in the API Explorer. Note the **\_views** system field that shows the number of views for a content item. This field is optional. We recommend not using it to optimize cache efficiency. The result should look something like this: ```json copy { "data": { "Popular_Articles": { "items": [ { "_id": "0cbe2455-124c-4820-b2ac-dcc4261e150c", "title": "How to set up a Google Ads account", "_views": 83 }, { "_id": "dd42b8c4-4773-4fdd-a71f-87e57b35beaa", "title": "Building User Trust In UX Design", "_views": 59 }, { "_id": "79c453ed-ffe2-4aec-8fb2-f549e3775264", "title": "Building A Video Streaming App With Nuxt.js", "_views": 49 }, { "_id": "5a53b271-898e-4eef-b877-5863b34b6ff9", "title": "UI Design Testing Tools I Use All The Time", "_views": 40 }, { "_id": "dd3309eb-df84-4e4b-8fdf-80b31b8eb58a", "title": "The Rise Of Design Thinking As A Problem Solving Strategy", "_views": 29 }, { "_id": "f1d9b142-883f-4964-8d8f-cd2f255330a2", "title": "Why Customization Is Key For Entrepreneurs In The Digital Age", "_views": 21 }, { "_id": "885b71ac-5a4b-4d2e-9770-a4a6f20425e9", "title": "15 Tips On How To Brand Yourself Online", "_views": 11 }, { "_id": "ca0e0d37-600b-42f7-a013-9b0f8e18f127", "title": "The Evolution Of Jamstack", "_views": 9 }, { "_id": "f4b65d11-c2e2-4320-a363-e7d420d03ed2", "title": "Modeling A GraphQL API For Your Blog", "_views": 5 } ] } } } ``` ### Filtering the result The previous example included all items for retrieving the most popular items. But often, you want to make the result even more accurate. For example, only show items published recently or in a particular category. So let's see how you can do that. - Expand the query with the following parameters: ```graphql copy query { Popular_Articles( where: { _publish_on_gt: "2021-01-01T00:00:00+00:00" categories: { _slug_any: [ "ux-design", "development" ] } }, limit: 3 ) { items { _id title _views } } } ``` - We added `_publish_on_gt: "2021-01-01T00:00:00+00:00"` to show only articles published after January 1, 2021. Note the underscore at the beginning of the parameter. - We added categories: **`{ _slug_any: [ "ux-design", "development" ] }`** to limit the result to only articles in the “UX Design” or the “Development” categories. Note the square brackets because you’re dealing with an array. - We added `limit: 3` to limit the number of results to three items. Result: ```json copy { "data": { "Popular_Articles": { "items": [ { "_id": "dd42b8c4-4773-4fdd-a71f-87e57b35beaa", "title": "Building User Trust In UX Design", "_views": 59 }, { "_id": "79c453ed-ffe2-4aec-8fb2-f549e3775264", "title": "Building A Video Streaming App With Nuxt.js", "_views": 49 }, { "_id": "5a53b271-898e-4eef-b877-5863b34b6ff9", "title": "UI Design Testing Tools I Use All The Time", "_views": 40 } ] } } } ``` ## Want to learn more? Check out the following chapters: - [A/B testing](/ab-testing/setting-up-ab-testing) - [Personalization](/personalization/setting-up-personalization) ## Schedule a free consultation Do you want to get started with recommendations but still have questions or want a demo? [Schedule a free call](https://prepr.io/get-a-demo) with a Prepr solution engineer. Source: https://docs.prepr.io/recommendations --- # Integrations Extend Prepr CMS with one of the standard integrations listed below. If you need to build a custom integration, check out the [creating a custom remote source](/content-modeling/creating-a-custom-remote-source) or [using webhooks](/development/best-practices/webhooks) resources instead. Source: https://docs.prepr.io/integrations --- # The Prepr Next.js package *The Prepr Next.js package offers some helper functions and the Prepr preview toolbar for easier personalization and A/B testing implementation. This guide introduces you to the *Prepr Next.js package* and shows you how to use it.* ## Prerequisites - You need to have a [Next.js project connected to Prepr](/connecting-a-front-end-framework/nextjs/next-complete-guide/step-2-make-the-project-dynamic#connect-your-nextjs-website-to-prepr) before installing the package. ## Introduction The *Prepr Next.js* package includes the following features: - It provides API request headers for the following values: - Each visitor's customer ID. You need this API request header, `Prepr-Customer-Id`, when you query adaptive content and content with A/B testing. - Any UTM parameters, if applicable. This is useful to identify customers who enter your website through a social media campaign, for example. - HubSpot cookie, if it exists. This is useful for identifying customers who are tracked in HubSpot as a lead, for example. - The visitor's IP address. This is useful for localization. - The Prepr preview toolbar includes the following features: - Provides an easy way to test adaptive content and content with A/B test variants - Allows content editors to edit content through a link from the preview page.  - The package also allows you to enable Visual editing in your Prepr environment. Check out the [visual editing guide](https://docs.prepr.io/project-setup/setting-up-visual-editing#nextjs) for more details. For additional implementation options and technical details, check out the [Prepr Next.js package repo](https://github.com/preprio/prepr-nextjs) directly in GitHub. ## Installation To install the *Prepr Next.js package,* follow the steps below. 1. Run the following command in your Next.js project: ```bash copy npm install @preprio/prepr-nextjs ``` 2. Add the `PREPR_ENV` variable to the `.env` file. You can enable the Prepr preview toolbar for a staging environment by setting the value to `preview`. ```bash copy filename="./.env" {2} PREPR_GRAPHQL_URL=Some bold text and italic
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
", "format": null } } } } ``` ### Dynamic content The Dynamic content field contains embedded videos, social media posts, maps, assets, and components for rich content items like in the example request below. ```json copy { "items": { "en-US": { // The content item entry for this locale. "content": { // The API Id of the dynamic content field "items": [ { // Embedded heading text in the dynamic content field "id": "aa82833a-7b0c-413c-b8e5-e463efb32903", "created_on": "2023-09-27T15:05:25+00:00", "changed_on": null, "label": "Text", "body": "Ingredients", "format": "H2" }, { // Embedded bullet points in the dynamic content field "id": "d0ea8c21-0826-46ee-b559-3fb838daa1c7", "created_on": "2023-09-27T15:05:25+00:00", "changed_on": null, "label": "Text", "body": "| Pros | Cons |
| Tasty | Lots of calories |
| Easy to make | Need to use the oven |
| Pros | Cons |
| Tasty | Lots of calories |
| Easy to make | Need to use the oven |
Whether it's for a brunch, dinner or tea party, quiche is the perfect addition and can be extremely easy to prepare and customize to suit your and your guests' taste buds.
" }, // The API Id of a single line Text field "title": { "body": "Say quiche" } } } } ``` ## Update a content item To update an existing content item, send a `PUT` request to the `https://api.eu1.prepr.io/content_items/{id}` endpoint. Replace `{id}` with the Id of the content item to be updated. Make sure the `Content-Type` in the header is set to `application/json` to send a valid JSON body. Keep the following in mind when you create your update request: - Prepr doesn't merge content changes but completely updates a content item for a locale. So you must send the entire body for each locale that you want to update. - When updating one locale, any other locales that are not in the update request remain unchanged. - It's possible to update the `workflow_stage` of a locale without sending the items array. See an example below of an update to the workflow stage of an existing *Article* content item. ```json copy { "locales": [ "en-US" ], "workflow_stage": { // Update workflow stage to review "en-US": "Review" }, "assigned_to": { // Assign to a user to do the review "en-US": { "id": "1f71ff0a-f1f9-4cc3-85b4-bb8c7e33e4e0" // The Id of the existing user in this Prepr environment } } } ``` ## Patch a content item To only update specific fields on an existing content item, send a `PATCH` request to the `https://api.eu1.prepr.io/content_items/{id}` endpoint. Replace `{id}` with the Id of the content item to be updated. Make sure the `Content-Type` in the header is set to `application/json` to send a valid JSON body. Keep the following in mind when you create your patch request: - Only supported field types on the model level can be updated by the patch endpoint. - The updates done by the patch endpoint will not update the `changed_on` metadata of an item. The update is processed silently and doest effect the order when sorting on `changed_on`. - Field will be patched at root level, for example, if an Asset field is patched, you need to pass the full field content. - The `PATCH` will update the latest version of an item, if this version is currently a DRAFT the update will be published when the editor publishes the new version. If the version is already PUBLISHED, changes will be live immediately. - Webhook events are triggered the same as with standard updates. - Required fields will not trigger validation rules. See an example below of an update to the title of an existing *Post* content item. ```json copy { "locales": [ "en-US" ], "items": { "en-US" : { "title" : { "body" : "A new Post title" } } } } ``` The `PATCH` request supports the following field types: `Text`, `Enum`, `Color`, `Boolean`, `Integer`, `Float`, `Coordinates`, `Content reference`, `Asset`, `Date & Time` (single only), `Social`, `Form Embeds`, `Resource`, `Tag` ## Field types The list of field types in the `items` array of a content item depends on the related model. In the example `POST` requests above, you can see that the `api_id` of a field is used to list the field array in `items`. Go to **Schema → Model → Field type settings** to get the `api_id` of the fields that you want to include in the mutation request. For a full list of field types and available settings like validation rules, check out the [Schema field types doc](/content-modeling/field-types) for more details. Here is a list of field types that you might need to set up when you create or update a content item. ### Text The Text field can be a single line, multiple lines, or HTML. Set the `body` values like in the example request below. ```json copy { "locales": [ "en-US" ], "items": { "en-US": { // API Id of a single line text field "title": { "body": "Headline" }, // API Id of a text area field with multiple lines "my_text_area": { "body": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi u" }, // API Id of an HTML text field "my_html_text": { "body": "Some bold text and italic
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
" } } } } ``` ### List (Enum) The List field is a simple string with the content of the field. The content should match one of the values in the linked Enumeration. Set the values like in the example request below. ```json copy { "locales": [ "en-US" ], "items": { "en-US": { // API Id of a List field "align": { "body": "left" } } } } ``` ### Dynamic content Embed rich text, videos, social media posts, maps, and assets in this field to create rich content items like the [*Article* request example](#article-example). Below is a list of elements that you can embed in the dynamic content field. | Embedded element | Label | DESCRIPTION | |------------------|---------|-----------------------------------------------| | Text | `Text` | | | Asset| `Asset`| Use an `items` object to embed an asset and set the `id` to an existing asset in Prepr like in the example above.| | Location | `Coordinates` | Set the `latitude` and `longitude` values to embed a location. | Check out the [Remote content](#remote-content) and [Social](#remote-content) field type details to embed these in your dynamic content field. ### Assets Assets are images, videos, and audio files or documents that you can link to a content item. Set the `id` value to an existing asset in your Prepr environment like the example below. Check out the [Managing assets doc](/mutation-api/assets-upload-update-and-destroy) on how to upload assets using the REST API. ```json copy { "locales": [ "en-US" ], "items": { "en-US": { //API Id of the Asset field "cover": { "items": [ { // An Id of the asset that already exists in Prepr "id": "d7261363-a656-4b8e-bc39-506e6d6ab365" } ] } } } } ``` ### Integer Set an integer to store stock quantities, prices in cents, etc. like in the example below. ```json copy { "locales": [ "en-US" ], "items": { "en-US": { // The API Id of the Integer field "quantity": { // The number value "value" : 122 } } } } ``` ### Float Set number entries with decimal places, for a price of an item, distance, or weight, etc. like in the example below. ```json copy { "locales": [ "en-US" ], "items": { "en-US": { //The API Id of the Integer field "quantity": { // The number value with decimal points "value" : 122.22 } } } } ``` ### Boolean Set a boolean field to true or false like in the example below. ```json copy { "locales": [ "en-US" ], "items": { "en-US": { // The API Id of the boolean field "needs_social_post": { "value": true }, } } } ``` ### Stack The Stack field includes a list of (personalized) models/components. Check out the [stack field docs](/content-modeling/field-types#stack-field) for more details. In the example below, you can see a request for a *Page* content item. Check out the related *Page* model on a Prepr environment with Demo data or create a model from the *Page* template. ```json copy { "locales": [ "en-US" ], "items": { "en-US": { // The API Id of a stack field "stack": { // This element contains all components and items in the stack "items": [ { // Items object of a Page header component "items": { // The API Id of a text field in the component "cta_label": { "body": "Let's get baking!" }, // The API Id of a text field in the component "heading": { "body": "Welcome to our baking community" }, // The API Id of an asset field in the component "image": { "items": [ { // The Id of an existing image in this Prepr environment "id": "cf91df18-df0e-4a20-b84a-8ef448becef9" } ] }, // The API Id of a text field in the component "text": { "body": "Learn some basic steps to get started or kick your skills up a notch with our handy tips, recipes and products." } }, // Component Id of the page header component "id": "bc2c106b-9e9d-43a8-b8c4-8d72866a9b4b", }, { // Items object of a Image and Text component "items": { "image": { "items": [ { // The Id of an existing image in this Prepr environment "id": "6059ecee-270f-46b0-b286-2e3e9374d33a" } ] }, // The API Id of a List field "image_position": { "body": "Left" }, "text": { "body": "Everyone has their own way to crack an egg. Maybe they learnt it from a parent or from watching cooking videos. The truth is there is no \"best\" way. Practice makes perfect. Start with the back of a knife or fork and try not to get any shell pieces into your egg." }, "title": { "body": "The best way to crack an egg" } }, // The component Id for the image and text component "id": "906ac62d-b59d-4346-ac7f-bf10a92fbb22", }, { // Link to an existing Call to action content item "id": "51898d57-f507-475f-bc6b-7dc3405bbed5" } ] }, // The API Id of a text field in the content item "title": { "body": "Home page" } } } } ``` ### Content reference The Content reference field stores a link to one or more content items. Check out an Article example below with a content reference to a *Person* content item to link authors. ```json copy { "model": { // The Id of the Article model "id": "b2298bbf-eda1-4f5c-9648-9213ecef6746" }, "locales": [ "en-US" ], "workflow_stage": { "en-US": "In progress" }, "items": { "en-US": { // The API Id of the Content reference field // for linked Person content items "authors": { "items": [ { // The Id of an existing Person content item "id": "54515b1a-b6d6-4002-956a-39d809023921" } ] }, "title": { "body": "Say quiche" } } } } ``` ### Component Components are often used to represent a set of reusable fields. Also, it can be added as a custom element to the Dynamic content or Stack fields. In the example below we have an *Article* content item that has an *SEO* component. ```json copy { "locales": [ "en-US" ], "items": { "en-US": { // The API Id of the component field "seo": { // The list of fields based on the SEO component "items": { // The API Id of a text field in the component "description": { "body": "An easy french toast recipe" }, // The API Id of an asset field in the component "social_media_image": { "items": [ { // The Id of an existing asset in this Prepr environment "id": "6059ecee-270f-46b0-b286-2e3e9374d33a" } ] }, // The API Id of a text field in the component "title": { "body": "The easiest french toast recipe" } }, // The component Id for the embedded component "id": "906ac62d-b59d-4346-ac7f-bf10a92fbb22" } } } } ``` ### Remote content The Remote Source Response for a request with a Remote content field allows you to reference content in an external CMS, legacy system of eCommerce platform. [Check out the Remote source setup guide](/content-modeling/creating-a-custom-remote-source) to quickly setup your first integration. ```json copy { "locales": [ "en-US" ], "items": { "en-US": { // The API Id of the remote content field "kitchen_shop": { // The list of remote items for this content items "items": [ { // Id that matches the the item in the remote source "id": "2", // The main info about the item "body": "Spatula", "description": "We're willing to bet you reach for your spatula more often than you think. This tool is ideal for flipping the perfect pancake", // The URL where the image is stored "image_url": "https://prepr-example-show-content-demo-patterns.stream.prepr.io/w_1920,h_1080/2qanpdxyhf20-spatula.png", "content_integration": { // Id of the remote source from where the data will be synced "id": "c0263fe3-007e-4307-9792-7364f6c0cf06" } } ] } } } } ``` Content integration items in Prepr have a predefined schema. This means that the type for any content integration item in the REST API schema follows the definition above. ### Date & Time The DateTime field adheres to ISO 8601 standard. Check the field settings, to create or update this field correctly: - **The Type** - The structure of this field is different depending on the *Type*: *Date*, *Date range* or *Business hours*. - **Time selection** - When time selection is enabled, set the format to `Y-m-d H:i:s` instead of `Y-m-d`. - **Multiple dates** - When Allow extra dates is enabled, put the content in an `items` object like in the example below. ```json copy { "locales": [ "en-US" ], "items": { "en-US": { // API Id of a date field "event_date": { // Date only format "format": "Y-m-d", "value": "2023-01-01" }, // API Id of a date time field "start_date_and_time" : { // Format with time selection "format": "Y-m-d H:i:s", "value": "2020-10-19 12:00:00" }, // API Id of a date range field "project_duration": { // Date only format "format": "Y-m-d", "from": "2023-01-01", "until": "2024-12-31" }, // API Id of a date time range field "event_duration": { // Format with time "format": "Y-m-d H:i:s", "from": "2023-01-01 00:00:00", "until": "2024-12-31 23:59:59" }, // The API Id of a date range field with multiple date ranges "seasons": { "items": [ { "from": "2023-12-01", "until": "2024-02-29", "format": "Y-m-d" }, { "from": "2023-09-01", "until": "2023-11-30", "format": "Y-m-d" } ] }, // API of a Date and time field for Business hours "opening_times": { // List of days and corresponding business hours "items" : [ { "state": "open", // Number for corresponding day, 2 = Tuesday "open_day" : 2, // Opening time in 24 hour format "open_time" : "08:00", "close_day" : 2, // Closing time in 24 hour format "close_time" : "19:00" }, { "state": "open", // Number for corresponding day, 3 = Wednesday, etc. "open_day": 3, // Opening time in 24 hours format "open_time": "08:00", "close_day": 3, // Closing time in 24 hour format "close_time": "19:00" }, { // Example of an exception to the regular opening hours: Closed on Xmas day "state": "closed", "open_day": 4, "close_day": 4, "valid_from": "2025-12-25", "valid_until": "2025-12-26" } ] } } } } ``` ### Location The Location field allows content editors to add Google Maps geo-points (coordinates or an address) to your content item. ```json copy { "locales": [ "en-US" ], "items": { "en-US": { // The API Id of the Location field "event_location": { // Latitude value in Google maps "latitude": "21.3137", // Longitude value in Google maps "longitude": "-157.806" } } } } ``` ### Social Embed social posts in content items by adding a social URL. Set the `url` to a valid URL depending on the platform of the post. ```json copy { "locales": [ "en-US" ], "items": { "en-US": { // The API Id of the Social field in the content item "cooking_posts": { "url": "https://twitter.com/CookingChannel/status/1059520829841661954" } } } } ``` ### Color Add a Color field, by setting the HEX code like in the example request below. ```json copy { "locales": [ "en-US" ], "items": { "en-US": { // The API Id of the color field "border_color": { // The Hex color code "body": "#000000" } } } } ``` ### Tag Add tags (keywords) to your content item like in the example request below. ```json copy { "locales": [ "en-US" ], "items": { "en-US": { // The API Id of the Tags field in the content item "search_keywords": { // An items array with a list of tags "items": [ { "body": "awesome", }, { // Id of an existing tag "id": "3dbf4dbe-9c87-4bae-9b23-7ae685655ea1", }, { // slug of an existing tag "slug": "more-than-great", }, ] } } } } ``` Source: https://docs.prepr.io/mutation-api/content-items-create-update-and-destroy --- # Publish a single item To publish or schedule a content item, use the following endpoint: ```http copy PATCH: /content_items/{id}/{locale}/publish ``` Optionally a UNIX timestamp can be sent with the request to schedule the item to be published at a later time. ```json copy { // UNIX Timestamp "publish_on" : 2342321312 } ``` If the request is successful the API will return status code 200. This endpoint will trigger the `content_item.published` event. Source: https://docs.prepr.io/mutation-api/content-items-publish --- # Unpublish a single item To unpublish a published version of a content item, use the following endpoint: ```http copy PATCH: /content_items/{id}/{locale}/unpublish ``` If the request is successful the API will return status code 200. This endpoint will trigger the `content_item.unpublished` event. Source: https://docs.prepr.io/mutation-api/content-items-unpublish --- # Delete a single item There are two options to delete an existing content item. You can either delete a specific language variant for a content item or delete the content item as a whole. For both operations the scopes `content_items` and `content_items_delete` are required. ## Delete a language variant in the content item To delete a specific language variant for a locale in the existing content item, request the following endpoint with the HTTP `DELETE` method. ```http copy DELETE: /content_items/94c56d8a-c54e-4b46-9971-a83bf06dcf52/en-US ``` Replace the `UUID` and the `locale` with the content item ID and locale you want to delete. If the request is successful the API will return an empty response and status code 204. ## Delete the entire content item To delete the content item as a whole, request the following endpoint with the HTTP `DELETE` method. ```http copy DELETE: /content_items/94c56d8a-c54e-4b46-9971-a83bf06dcf52 ``` Replace the `UUID` with the content item ID you want to delete. If the request is successful the API will return an empty response and status code 204. Source: https://docs.prepr.io/mutation-api/content-items-deleting --- # Fetching assets Prepr stores all your digital assets in the Media Library (in Prepr: the Media tab), making it easy to access, view, and manage your assets. You can add, edit, download, or delete files whenever needed; categorize, search, and filter assets on multiple attributes to find the right one quickly. ## The Asset object ```json copy { "id": "df7c1544-bad0-4c9d-928f-0c9f684c9ceb", "created_on": "2023-06-13T14:35:54+00:00", "changed_on": "2023-06-13T14:35:54+00:00", "label": "Photo", "name": "Sed et augue non mi dapibus tincidunt sollicitudin vel leo", "body": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis vel ornare massa. Ut vehicula commodo consequat.", "author": "Marc van Dam", "status": null, "reference_id": "dam-249387", "width": 1020, "height": 1020, "original_name": "sed-et-augue.jpg", "mime_type": "image/jpeg", "cdn_files": { "total": 1, "items": [ { "id": "bfaac48b-fb0d-4d12-84da-af8d65244c4b", "created_on": "2023-06-12T08:44:43+00:00", "label": "CdnFile", "file": "371apne44zy3.jpg", "url": "https://example.stream.prepr.io/{format}/371apne44zy3-5az.jpg" } ] }, // Additional fields in the Asset model for the default locale // Boolean field to mark an asset copyrighted "copyrighted" : true, "author_name": { "body" : "John Captura", //An HTML text field for Author name }, "price": 12.50, // Number field for price // Additional fields in the Asset model for other locales // Pass the localized param to get the fields for other locales "localized" : { "de-DE" : { "copyrighted" : true } } } ``` | FIELD | DESCRIPTION | |---------------|------------------------------------------------------| | id | Unique identifier for each item. | | created\_on | UTC time at which the asset was created/upload. | | changed\_on | UTC time at which the asset was last updated. | | label | Identifier for the object. | | name | Name of the asset. | | body | Description of the asset. | | reference\_id | Custom asset API ID. | | author | Optional name of the author. | | width | Width of the image of video. | | height | Height of the image of video. | | original\_name | Name of the uploaded file. | | mime\_type | Mime type of the original file. | | cdn\_files | Object containing an array of `items`, the url field can be used for media playback. | ## Query by ID Since IDs are unique in Prepr, you can find the asset you want using the id argument. Here is an example that demonstrates how to query an asset with the ID "535c1e-...": ```http copy GET: /assets/535c1e-4d52-4794-9136-71e28f2ce4c1 ``` Source: https://docs.prepr.io/mutation-api/fetching-single-assets --- # Fetching assets Prepr stores all your digital assets in the Media Library (in Prepr: the Media tab), making it easy to access, view, and manage your assets. You can add, edit, download, or delete files whenever needed; categorize, search, and filter assets on multiple attributes to find the right one quickly. ```http copy GET: /assets ``` ## Search Prepr assets can be searched on their title or text fields. ```http copy GET: /assets?q[0][fz]=Beach Club ``` ## Types Assets can be filtered on their type. Available options are: `Photo`, `Video`, `Audio`, `Document`. ## Tags Assets can be filtered on their tags. You can query the tag fields by using the `tags` argument. ## Content Item relation Assets can be filtered on their relation to content items. ## Collections Assets can be filtered on their relation to collections. You can query the collections fields by using the `collections` argument. ```http copy GET: /assets?collections[0][eq]={ID} ``` ## Query by Reference ID The *Reference ID* is useful for storing external asset Ids. For example, during the migration of assets from another system. Check out the [Migration doc](/project-setup/migrating-content) for more details. Here is an example that demonstrates how to query an asset with a *Reference ID* value. ```http copy GET: /assets?reference_id[0][eq]=123456 ``` # Sorting You can use the `sort` argument to order your query results in a particular order. ```json copy { "sort": "created_on" } ``` ## Sort by metadata fields It is possible to sort by the assets created, changed dates in either ascending or descending order. The current values for sorting those fields are `created_on`, `-created_on`, `changed_on`, `-changed_on`. ## Default ordering If you don't pass an explicit order value the returned assets will be ordered descending by asset changed on timestamp `-changed_on`. This means that the most recently changed asset will appear at the top of the list. Source: https://docs.prepr.io/mutation-api/fetching-multiple-assets --- # Managing assets Use the REST API to do bulk mutation of assets when the [Media library UI](/content-management/managing-assets/managing-assets) is not an efficient option. For example, to upload assets as part of a project to migrate content from a legacy system to Prepr CMS. Before calling a REST API endpoint to manage the assets, go to **Settings → Access tokens** to create an access token with *REST API scopes* defined below. If you already have an access token for a related mutation in the same workflow, for example, a content migration project, simply add the relevant *REST API scopes* to this access token. ## The Asset object When uploading or updating an asset, you can include some additional information about the asset in the body of your request like in the example below. ```json copy { "name": "Example cover image", // If the name is not filled, the API will use the file name in this field. "body": "This is an asset that I uploaded using REST API.", // A description for this asset. "author": "Image Designer", // The author of the asset. "reference_id": "12345678", // An external ID for the asset, for example an ID from a legacy system. "tags": { // Include a list of related keywords to find the asset easily // For each tag, set either the ID, body or slug "items": [ { "id": "3dbf4dbe-9c87-4bae-9b23-7ae685655ea1" // ID of an existing tag in Prepr }, { "body": "dynamic" // If this tag doesn't exist, it will automatically be created }, { "slug": "dynamic-page" // If this tag doesn't exist, it will automatically be created } ] } "collections": { // Add this asset to a collection of similar assets "items": [ { "id": "ebc7fd2c-2458-4f2f-b7f5-5487f63d412a", // ID of an existing collection. Check out the Collections doc for more details. } ] } } ``` ## Upload new files Add the *REST API scopes* `assets` and `assets_publish` to the access token. The event `asset.created` will be fired when a new asset is created. ### Upload Image + Document + Audio To upload documents, photos, audio files, or cover images, send a `POST` request to the `https://api.eu1.prepr.io/assets` endpoint. - If the files are available locally, add the `"source"` parameter to specify a file like in the example below. Make sure the `Content-Type` in the header is set to `multipart/form-data` to send a valid asset file. * If the assets are located on a different server, set the `url` parameter to the URL location of the file like in the example code below. In this case, make sure the `Content-Type` in the header is set to `application/json`. You can upload files up to 25MB using the `url` parameter. When the upload is successful an auto-generated ID of the new asset will be returned in the response of this request. This ID can then be used to fetch the asset if needed. ### Upload Video To upload videos follow the steps below to upload each video in chunks. Make sure to handle errors and resume the upload of any remaining chunks before finishing the upload of a video. #### Step 1: Split the video into chunks First split each video into 25MB (26214400 bytes) chunks using the bash command below. ```bash copy split -b25m {filename} ``` #### Step 2: Start an upload session Start a resumable upload by initializing a new asset object. To make a start request and create a video upload session, send a `POST` request to the `https://api.eu1.prepr.io/assets` endpoint. Set the parameters as shown in the example below. When the upload is started successfully an auto-generated ID of the new asset will be returned in the response of this request. This ID can then be used in the request to upload the chunks and finish the request. #### Step 3: Upload chunks Now that the upload session has started and you have chunks ready to upload, make a transfer request to upload each chunk in the order that they are split. To upload the first video chunk, send a `POST` request to the `https://api.eu1.prepr.io/assets/{id}/multipart` endpoint and set the parameters like in the example below. Replace `{id}` with the ID returned in the response of the previous request. #### Step 4: Complete the upload Once you upload all chunks, make a finish request to complete the upload, post the video, and queue it for asynchronous video-encoding. Send a `POST` request to the `https://api.eu1.prepr.io/assets/{id}/multipart` endpoint and set the parameters like in the example below. Replace `{id}` with the ID returned in the response of the [start session request](#step-2-start-an-upload-session). ## Update To update an existing asset, add the *REST API scopes* `assets` and `assets_publish` to the access token. Send a `PUT` request to the `https://api.eu1.prepr.io/assets/{id}` endpoint. The `asset.changed` event will be fired when the asset is changed. Source: https://docs.prepr.io/mutation-api/assets-upload-update-and-destroy --- # Delete a single asset To delete the asset, request the following endpoint with the HTTP `DELETE` method. The scopes `assets` and `assets_delete` are required. ```http copy DELETE: /assets/94c56d8a-c54e-4b46-9971-a83bf06dcf52 ``` Replace the `UUID` with the asset ID you want to delete. If the request is successful the API will return an empty response and status code 204. Source: https://docs.prepr.io/mutation-api/delete-single-asset --- # Asset Collections A Collection represents a set of media files grouped by specific attributes and includes all types of assets. It can be a collection of images, videos, documents or audio files. ## The Collection object ```json copy { "id": "df7c1544-bad0-4c9d-928f-0c9f684c9ceb", "created_on": "2023-06-13T14:35:54+00:00", "changed_on": "2023-06-13T14:35:54+00:00", "label": "Collection", "body": "Branding & backgrounds" } ``` | FIELD | DESCRIPTION | |---------------|------------------------------------------------------| | id | Unique identifier for each item. | | created\_on | UTC time at which the asset was created/upload. | | changed\_on | UTC time at which the asset was last updated. | | label | Identifier for the object. | | body | Name of the collection. | ## Create, update or destroy ### Create a new collection To create a collection. ```http copy POST: /collections ``` ### Update an existing collection To update a collection. ```http copy PUT: /collections/{id} ``` ### Destroy an existing collection To destroy a collection. ```http copy DELETE: /collections/{id} ``` ## Managing collections ### Add assets to a collection To add assets to an existing collection, use the example below. This process only adds new assets to the collection. If this collection already has assets, these remain in the collection unchanged and duplicate entries are simply ignored. ```json copy { "items" : [ { "id" : "234h-432847-x23498-763x4-324x234" // The Asset ID, you can add mulitple assets at once. }, { // "id" : "30f064f4-8acb-4ee9-9e79-81d7029cc0c7" } ] } ``` ```http copy POST: /collections/{id}/assets ``` ### Remove assets from a collection To remove assets from an existing collection, use the example below. ```json copy { "items" : [ { "id" : "234h-432847-x23498-763x4-324x234" // The Asset ID. } ] } ``` ```http copy DELETE: /collections/{id}/assets ``` ### Set a collection cover To set a cover of the collection. ```http copy POST: /collections/{id}/cover?id={assetId} ``` ## Scopes `collections`, `collections_publish`, `collections_delete` Source: https://docs.prepr.io/mutation-api/assets-collections --- # Resizing ## Introduction The Images API is a read-only API for delivering images to apps, websites and other touchpoints. The Images API is available via a global CDN. The server closest to the user serves all content, which minimizes latency and especially benefits mobile apps. Hosting content in multiple global data centres also improves the availability of content. You can request images in specific sizes and crops. Images are returned with a `cdn_files` field. This object returns a `url` param that you can use as a basis for resizing the image needed for your app. The URL contains a part that is returned as `{format}` you need to replace this with the desired format. | argument | type | required | description | |----------|-------------| -------------| -------------| | `w` | String | false | Defines the width. | | `h` | String | false | Defines the height. | | `q` | String | false | Defines the image quality. | | `c` | String | false | Defines the crop. Default: `centre`. Options: `north`, `northeast`, `east`, `southeast`, `south`, `southwest`, `west`, `northwest`, `center`, `centre` | The format is constructed as `{option}_{value}` so if we would want to get the image in a 200px width form, `{format}` should be replaced with `w_200`. To simplify this it's possible to let the API construct those URLs for you. Just add them as an extra field in the `cdn_files` field. This extra field is called `resized`. ## Example We want a `landing` image of 232x232 and a `thumb` of 123x123. The fields are constructed as followed: ```http copy GET: /assets/{id}?fields=cdn_files{resized{landing.width(232).h(232),thumb.width(123).h(123)}} ``` Example response: ```json copy { // Particle response of /assets endpoint. "cdn_files": { "total": 1, "items": [ { "id": "bfaac48b-fb0d-4d12-84da-af8d65244c4b", "created_on": "2023-06-12T08:44:43+00:00", "label": "CdnFile", "file": "371apne44zy3.jpg", "url": "https://example.stream.prepr.io/{format}/371apne44zy3-5az.jpg" "resized": { "landing": "https://example.stream.prepr.io/w_232,h_232/371apne44zy3.jpg", "thumb": "https://example.stream.prepr.io/w_123,h_123/371apne44zy3.jpg" } } ] } } ``` This will add an extra param(s) to the object with the pre-rendered URL. It is possible to add up to 3 different formats into the request. Source: https://docs.prepr.io/mutation-api/assets-resizing --- # Managing asset lifecycles *This guide provides step-by-step instructions on managing asset lifecycles in Prepr with support for custom transcoding or streaming services. Available exclusively to enterprise plan customers.* ## The asset lifecycle The below stages make up the simple asset lifecycle. ## Integrating with external platforms The steps below shows you how to handle key events when integrating with external platforms. ## Adding a cover thumbnail You can use the standard mutation API `post` endpoint to add a cover to your asset. Check out the [Manage assets doc](/mutation-api/assets-upload-update-and-destroy#upload-new-files) for more details. Source: https://docs.prepr.io/mutation-api/assets-integration --- # Fetching segments Customer segmentation organizes customers into specific groups based on shared characteristics or similar behavior that matter for your use cases. These groups represent different target audiences for your business, making it easier to deliver more relevant content and experiences to your web app visitors. ## The Segment object ```json copy { "id": "df7c1544-bad0-4c9d-928f-0c9f684c9ceb", "created_on": "2023-01-23T14:34:59+00:00", "changed_on": "2023-01-23T14:34:59+00:00", "label": "Segment", "body": "Marketing campaign YYY", "reference_id": "utm-source-google-ads", "query": "{\"viewed\":[{\"param\":\"Body\",\"publication_tags_in\":[\"google-ads\"]}]}" } ``` | FIELD | DESCRIPTION | |--------------|-------------------------------------------------------------| | id | Unique identifier for each item. | | created\_on | UTC time at which the segment was created. | | changed\_on | UTC time at which the segment was last updated. | | label | Identifier for the object. | | body | Name of the segment. | | reference\_id | Custom segment API ID. | | query | JSON of the segment conditions. | ## Fetching all segments ```http copy GET: https://api.eu1.prepr.io/segments ``` The pagination of the segments endpoint is identical to the [content items endpoints](/mutation-api/fetching-paginating-collections). ## Query by ID Since IDs are unique in Prepr, you can find the segment you want using the id argument. Here is an example that demonstrates how to query a segment with the ID "535c1e-...": ```http copy GET: https://api.eu1.prepr.io/segments/535c1e-4d52-4794-9136-71e28f2ce4c1 ``` Source: https://docs.prepr.io/mutation-api/segments --- # Fetching tags A Tag is a meaningful label you can assign to your content items, customers and assets to differentiate between them while filtering. ## The Tag object ```json copy { "id": "df7c1544-bad0-4c9d-928f-0c9f684c9ceb", "created_on": "2023-01-23T14:34:59+00:00", "changed_on": "2023-01-23T14:34:59+00:00", "label": "Tag", "body": "Amsterdam", "slug": "amsterdam" } ``` | FIELD | DESCRIPTION | |------------|-------------------------------------------------------------| | id | Unique identifier for each item. | | created\_on | UTC time at which the segment was created. | | changed\_on | UTC time at which the segment was last updated. | | label | Identifier for the object. | | body | Name of the tag. | | slug | Custom tag API ID. | ## Fetching all tags ```http copy GET: /tags ``` The pagination of the tags endpoint is identical to the [content items endpoints](/mutation-api/fetching-paginating-collections). ## Query by ID Since IDs are unique in Prepr, you can find the tag you want using the id argument. Here is an example that demonstrates how to query a tag with the ID "535c1e-...": ```http copy GET: /tags/535c1e-4d52-4794-9136-71e28f2ce4c1 ``` ## Managing tags ### Fields | argument | type | required | description | | ------------- |-------------| -------------| -------------| | `body` | String | true | Defines the tag. | ```json copy { "body": "Dog" } ``` ### Create To create a tag. ```http copy POST: /tags ``` ### Update To update a tag. ```http copy PUT: /tags/{id} ``` ### Destroy To destroy a tag. ```http copy DELETE: /tags/{id} ``` ## Tag Groups ### Fetching all tag groups ```http copy GET: /tag_groups ``` ### Managing tag groups #### Fields | argument | type | required | description | |-----------|--------|----------|-------------------------------------------| | `body` | String | true | Defines the name of the tag group. | | `tags` | Object | false | Defines the tags inside of the tag group. | ```json copy { "body": "Taggroup 1", "tags": { "items": [ { "id": "00a92e60-24bd-4908-a36c-96268465111f", "body" : "Amsterdam" } ] } } ``` #### Create To create a tag group. ```http copy POST: /tag_groups ``` #### Update To update a tag group. ```http copy PUT: /tag_groups/{id} ``` #### Destroy To destroy a tag group. ```http copy DELETE: /tag_groups/{id} ``` Source: https://docs.prepr.io/mutation-api/tags --- # Fetching customers Customers are all persons who have interacted with your content. Meaning all persons who have read, clicked, shared, bookmarked, or commented on content items. A customer profile is created for each person. You can manage these profiles in Prepr. With this, we enable you to segment and personalize content for your customers. ## The Customer object To expand the customer object when querying a customer add the field name below in the `fields` parameter. ```json copy { "id" : "234h-432847-x23498-763x4-324x234", "first_name": "Jhon", "last_name": "Doe", "date_of_birth": "2000-12-01", "email" : "jhon.doe@gmail.com", "phone" : "31641356222", "tags": { "items": [ { "body": "Amsterdam" } ] } } ``` | field name | type | required | description | |------------------|--------|----------|-----------------------------------------------------------------------| | `id` | String | - | - | | `first_name` | String | false | Lists the first name of the customer. | | `last_name` | String | false | Lists the last name of the customer. | | `date_of_birth` | String | false | Lists the date of birth of the customer. Format: `Y-m-d`. | | `email` | String | false | Email address of the customer. | | `phone` | String | false | Phone number of the customer. | | `reference_id` | String | false | Lists the reference\_id of the customer. | | `tags` | Object | false | Lists tags of the customer. | | `segments` | Object | false | Lists the segment the customer is in. | ## Fetching all customers If you want to fetch a collection of customers. ```http copy GET: https://customers.prepr.io/ ``` How to filter the customs is explained on the [Filtering customers](/mutation-api/customers-query-all) page. ## Query by ID Since IDs are unique in Prepr, you can find the customer you want using the id argument. Here is an example that demonstrates how to query an customer with the ID "535c1e-...": ```http copy GET: https://customers.prepr.io/{{uuid}}?fields=custom,email,phone,tags ``` Source: https://docs.prepr.io/mutation-api/customers --- # Filtering the customer list If you want to fetch a collection of customers. ```http copy GET: https://customers.prepr.io/ ``` ## Text search Filter customers by searching in name, company and email fields. ```json copy { "q" : [ { "fz" : "Donald T" } ] } ``` ## Query by email Find a customer by using an email address. ```json copy { "email_eq" : "mail@example.com" } ``` ## Query by reference ID Find a customer by using a Reference ID. ```json copy { "reference_id_eq": "323c93d0-dd2c-40d1-90fb-7454ea06761d" } ``` ## Query by segments Prepr customers can be filtered on segments. You can query the segments field by using the `segments` as an argument. ### Customers that are in the specified segment This example requests all customers in the specified segment. ```json copy { "segments": [ { "eq": "323c93d0-dd2c-40d1-90fb-7454ea06761d" // Segment Id } ] } ``` ### Customers that are in on of the following segments This example requests all customers in one of the specified segments. If a customer is in both segments it will be returned once. ```json copy { "segments": [ { "in" : [ "323c93d0-dd2c-40d1-90fb-7454ea06761d", "8c4b2a7b-9827-4e57-8bd5-1ef04a046238" ] } ] } ``` ## Query by tags If you want to filter customers by related tags. ### Customers that have a specified tag ```json copy { "tags": [ { "eq": "323c93d0-dd2c-40d1-90fb-7454ea06761d" // Tag Id } ] } ``` ### Customers that have one of the following tags ```json copy { "tags": [ { "in" : [ "323c93d0-dd2c-40d1-90fb-7454ea06761d", "8c4b2a7b-9827-4e57-8bd5-1ef04a046238" ] } ] } ``` ### Customers that have all of the following tags ```json copy { "tags": [ { "all" : [ "323c93d0-dd2c-40d1-90fb-7454ea06761d", "8c4b2a7b-9827-4e57-8bd5-1ef04a046238" ] } ] } ``` ### Customers that have none of the following tags ```json copy { "tags": [ { "nin" : [ "323c93d0-dd2c-40d1-90fb-7454ea06761d", "8c4b2a7b-9827-4e57-8bd5-1ef04a046238" ] } ] } ``` ## Expanding fields To request more customer data check out the [Query by ID](/mutation-api/customers#query-by-id) page. ## Sorting customers You can use the `sort` argument to order your query results in a particular order. ```json copy { "sort": "created_on" } ``` It is possible to sort the customers by created, changed, last seen dates in either ascending or descending order. The current values for sorting those fields are `created_on`, `-created_on`, `changed_on`, `-changed_on`, `last_seen`, `-last_seen`. ## Pagination Prepr returns collections of resources in a wrapper object that contains extra information useful for paginating overall results. ```json copy { "skip": 0, "limit": 2 } ``` Will result in: ```json copy { "items": [{...},{...}], "total": 98, "skip": 0, "limit": 2 } ``` In the above example, a client retrieves the next 100 resources by repeating the same request, changing the `skip` query parameter to `100`. You can use the sort parameter when paging through larger result sets to keep the order predictable. For example, `sort=-created_on` will order results by the time the resource was created. ### Limit You can specify the maximum number of resources returned as a limit query parameter. **Note:** The maximum number of resources returned by the API is 1000. The API will throw a Bad Request for values higher than 1000 and values other than an integer. The default number of resources returned by the API is 100. ### Skip You can specify an offset with the skip query parameter. **Note:** The API will throw a Bad Request for values less than 0 or values other than an integer. By combining skip and limit you can paginate through results: `Page 1: skip=0, limit=15 Page 2: skip=15, limit=15 Page 3: skip=30, limit=15 etc.` Source: https://docs.prepr.io/mutation-api/customers-query-all --- # Create, update & destroy customers ## The Customer object ```json copy { "first_name": "Jhon", "last_name": "Doe", "date_of_birth": "2000-12-01", "email": "jhon.doe@gmail.com", "phone": "31612345678", "tags": { "items": [ { "body": "Amsterdam" } ] } } ``` | argument | type | required | description | |------------------|-------------| -------------| ------------| | `id` | String | | | | `first_name` | String | false | Defines the first name of the customer. | | `last_name` | String | false | Defines the last name of the customer. | | `date_of_birth` | String | false | Defines the date of birth of the customer. Format: `Y-m-d`. | | `email` | String | false | Defines email address of the customer. | | `phone` | String | false | Defines phone number of the customer. | | `reference_id ` | String | false | Defines the reference\_id of the customer. | | `tags ` | Object | false | Defines tags of the customer. | ## Create To create a customer. ```http copy POST: https://customers.prepr.io/ ``` Scopes: `customers` `customers_publish` ## Update To update an existing customer. ```http copy PUT: https://customers.prepr.io/{id} ``` Scopes: `customers` `customers_publish` ## Destroy To delete a customer. ```http copy DELETE: https://customers.prepr.io/{id} ``` Scopes: `customers` `customers_delete` Source: https://docs.prepr.io/mutation-api/customers-create-update-and-destroy --- # Signing-up customers Customers represent anonymous and registered people that are engaging with your content. They usually represent website visitors or shop buyers. The Customer API provides methods to get, create, update and delete. ## Creating a new customer You can create a new Customer in your Prepr environment. ```http copy POST: https://customers.prepr.io/ ``` ### Fields | argument | type | required | description | |------------------|-----------| -------------|---------------------------------------------------------------------------| | `first_name` | String | false | Defines the first name of the customer. | | `last_name` | String | false | Defines the last name of the customer. | | `date_of_birth` | String | false | Defines the date of birth of the customer. Format: `Y-m-d`. | | `source` | String | false | Mostly used to define imports etc. | | `email` | String | false | Email addresses of the customer. | | `phone` | String | false | Phone number of the customer. | | `reference_id ` | String | false | Defines the reference\_id of the customer. | | `tags ` | Object | false | Defines tags of the customer. | | `sign_in ` | Boolean | false | Will add a sign in token to the response after creating the new customer. | ```json copy { "first_name": "Jhon", "last_name": "Doe", "date_of_birth": "2000-12-01", "source" : "ios app", "email": "jhon.doe@gmail.com", "phone": "31612345678", "tags": { "items": [ { "body": "Amsterdam" } ] } } ``` Source: https://docs.prepr.io/mutation-api/sign-up-introduction --- # Sign-in with a magic link How to Build Magic Link sign-in. ## Setting-up the email template **Creating a HTML template**\ You can create your own email template to be sent to your customers. First, create an HTML template using your preferred code editor. Then follow the steps below to add it Prepr. **Signing in to your Prepr account**\ Go to [https://signin.prepr.io](https://signin.prepr.io) and sign in with your Prepr account. Then navigate to the Environment you want to create the Sign-In for. **Save the email template**\ Go to **Settings → Email templates** and click **Add template**. Enter a name, and a reply email address like this `Prepr
```
You can enable or disable text alignment in the model and element fields.

***
## Model and element design update
Today we launched a completely new design for managing models and elements. This new design has been implemented to give you an even faster and more enjoyable content modeling experience. Adding or changing fields has become super clear through the use of tabs in the modals.
Let us know about your experience with content modeling in Prepr! [Send us an email to give feedback](mailto:feedback@prepr.io).

***
## Manage the API names of your model
For each content model in your Prepr environment the GraphQL API creates a corresponding GraphQL Type. The Type name is a PascalCase version of the content model name, stripped of all non-alphanumeric characters. Since today's update, you can manage the names of the Singular type and the Plural type. The given display name results in a singular and plural name; both can be overwritten manually.

***
## Overall performance upgrade
*January 6th, 2022*
At Prepr, we find it very important that our application works fast and that all users can quickly perform their tasks in our system. That's why we ended the year with a performance upgrade in which we thoroughly reviewed the code in Prepr CMS. We found out that several code snippets were slowing things down. Therefore, the team optimized specific code snippets for speed. This has improved the performance of the whole system. We hope you've noticed the difference and have optimized your workflow.
***
## Personalize digital content at scale for exceptional customer experiences
*January 3rd, 2022*
We all know by now how important it is to approach your customers in a personal way with targeted content. But how do you do that? Many companies struggle with this because they don't have enough data, content, or know-how. Next month there will be a major beta release of the personalization engine for a select group of customers.
With the updated personalization engine, it will be even easier to deliver hyper-personalized content. We will then introduce Content Targeting which allows you to very easily specify exactly what content should be shown to a particular visitor segment. For example women or men. Or people who have visited a specific section of your website. You can then show them specific banners that are tailored to their preferences and thus improve engagement with your content.

Source: https://docs.prepr.io/stay-updated/changelog2022
---
# Changelog 2023
Find the beautiful features and important updates that were added to Prepr in 2023. This changelog gives you an insight into the most eye-catching releases during this period.
[Latest](/changelog) | [2024](/stay-updated/changelog2024) | **2023**
## Ensure content integrity with our new unique field validation
*November 21st, 2023*
As you've requested, we've added a validation to check for unique field values in content items. This validation is available for [*Single line Text*](/content-modeling/field-types#text-field) and [*Number*](/content-modeling/field-types#number-field) fields. Not only does this prevent content editors from entering duplicate values, but it also means you don't need this additional check in your code when updating or inserting content items through the [Mutation API](/mutation-api/content-items-create-update-and-destroy).
To activate this validation, simply enable the **This field must be unique** toggle under the *Validation* tab for the chosen field. When done, an error will be triggered when a content editor or an API request tries to save a content item with a field value that already exists in the same field in another content item in the environment.

***
## Enable Personalization and A/B testing
*November 16th, 2023*
It is now possible to enable or disable personalization and A/B testing on a stack field. As a content modeler, this gives you more control over which content items can have personalization and A/B testing added to them. Limit these features to relevant models by enabling or disabling these features on the stack field in the model.

***
## Choose workflow stage to trigger required validation
*November 6th, 2023*
As requested, we've added a feature for you to choose when to trigger the required field validation for content items. Previously, the editor could save content items without filling in required fields and they only got an error for missing required values when the workflow stage was updated to *Done*.
This new feature gives you the flexibility to choose the workflow stages that will trigger the required field validation. In the **Settings → General** screen, simply choose the workflow stages of the content item that will trigger the required field validation, for example, *In Progress*, *Review* and *Done*. *Done* is selected by default.

***
## Enable Strict Mode to support TypeScript
*November 6th, 2023*
We are pleased to bring you a feature to enable *Strict Mode* on the GraphQL schema. This means you will get accurate TypeScript types from your GraphQL schema which in turn means simpler, cleaner and more consistent code when processing GraphQL requests. For example, the strict GraphQL type of `String!` will never be null as opposed to the `String` type.
In the **Settings → Access Tokens** screen, enable *Strict Mode* for a specific GraphQL access token.

***
## Integrate with Typesense for content searches
*November 3rd, 2023*
We’re happy to announce that you can now integrate Prepr and Typesense to provide users with fast and flexible searches across your web app content.
Setting up the Typesense integration in your Prepr is easy. With just a few clicks, you can connect Prepr to your Typesense application, and Prepr will handle the rest automatically.

Check out the [Typesense integration doc](/integrations/typesense) for more details.
***
## Role permission to delete content items
*October 12th, 2023*
As requested, we've added a feature to set special permission for users to delete content items. This gives you more flexibility when defining roles for different types of content editors.
Simply enable or disable the option **Allow user to delete content items** in the user role.

***
## Purge access token cache
*October 11th, 2023*
It's now possible to purge content cache linked to a specific access token. This means that developers can make sure that API requests made with the purged access token will return fresh content when needed, for example when you need a real-time sync of new content related to an important product launch or you need to clear old versions of data in the case of a manual deployment.
Simply click the **Purge token cache** button for the access token for which you want to purge the cache.

For more details check out the [GraphQL caching doc](/graphql-api/caching).
***
## Drafts for published content items
*September 29th, 2023*
We are happy to bring you a renewed workflow to publish your content items. Now you can make changes to already published content items without affecting the published version. You can then explicitly publish or schedule the content item when it's ready. This means that you have complete control over changing and republishing previously published content items.
Once you've created a content item and want it published to the web app, simply click **Publish and close** to publish it right away. You can easily make updates to the published content item directly and then click the **Save** button. This will save the changes without publishing them. This means there'll be two versions; your saved version and the published version.

You can still schedule your content items to be published at a later date, now with just a click of the **Schedule** button. Enter the *Publish on* date and click the **Schedule** button and that's it. You can also enter an *Unpublish on* date for temporary content.

When publishing your content items, the workflow stage of the content item will be updated to *Done* automatically.
For more details, check out the [Manage content item docs](/content-management/managing-content/managing-content-items#publish-a-content-item).
***
## Specify which text fields you want to automatically translate
*September 12th, 2023*
We recently added an AI-powered auto-translation feature to Prepr. While we've received a lot of positive feedback, some customers have expressed a desire for settings to skip or ignore auto-translation. This update allows users to specify which text fields should be ignored during automatic translation.

***
## Check linked and unused assets
*September 12th, 2023*
We are happy to bring you a long-awaited update to the media library. It is now possible to check if an asset is being used in any content items. This view helps you when deciding which assets can be deleted.
There is a new filter checkbox called *Unused*. When you select the *Unused* checkbox, all the assets that are not used in any content items will be shown.

Open a specific asset to see a list of content items that use this asset.

***
## View system fields in the Schema Editor
*August 1st, 2023*
As requested, we've added a feature to view the system fields directly in the Schema Editor when editing or viewing a model. This gives you the benefit of having an overall view of a model and direct access to the *API ID* of a system field that you can use in your API query requests.
Simply enable the **Show system fields** toggle at the top of your model to see the list of system fields. You can also see some help text and the *API ID* of each system field.

Check out the [Model docs](/content-modeling/managing-models#view-system-fields) for more details.
***
## AI translation of content items now available
*July 13th, 2023*
We are very excited to bring you the option to auto-translate your content items using AI. This will lighten the workload for content editors who need to create translated copies of a content item.
To use the new feature, go to the content item that you wish to translate. Simply, choose a language from the drop-down menu and click *Translate automatically using AI*. Choose a source language for the translation and that's it! The result is a machine-translated content item entry for the chosen language. You can then review and adjust the translation as needed before publishing.

Check out the [Localization doc](/content-management/localizing-content#working-with-multiple-locales) for more details.
***
## Support for multiple-asset and single-asset fields
*June 30th, 2023*
You can now choose between using a multiple-asset or single-asset field [when adding it to a model or component](/content-modeling/field-types#assets-field), depending on the number of assets you intend to add.
A *single-asset field* only allows for a single image, video, audio fragment, or file to be added. The API response for this field type is simpler since the API doesn’t return an array of assets. A single-asset field might be a better fit for content items such as author profiles or contact pages.
The *multi-asset field* allows for multiple assets to be added and is returned as an array by the API. You may want to use this field type for content items like articles and products.

This feature provides you with more flexibility in creating customized setups for your content and simplifies [querying assets](/graphql-api/schema-field-types#assets) using the API.
Check out our [asset guides](/content-management/managing-assets) to learn how to add assets to your web app.
To get this feature, upgrade you API to the latest version [2023-06-30](/graphql-api/upgrade-guide).
***
## New GraphQL API version released
*June 30th, 2023*
The latest version of the GraphQL API version, 2023-06-30, introduces a new recommendation algorithm to the API. All models now have a People Also Viewed recommendation query to serve your customers with content they are likely to enjoy and keep them engaged with your web app for longer.
This release also simplifies the querying of images. An asset field can now be configured as a single-asset field, removing unnecessary arrays when using an asset field with only one asset.
To take advantage of these features, upgrade to the latest version of the API. For more information, see the [upgrade guide](/graphql-api/upgrade-guide).
***
## Creating complex web pages is now easier with nested components
*June 23rd, 2023*
The introduction of nested components has made content modeling in Prepr even more powerful. In addition to adding a component to a model or Stack field, you can now [embed one component into another](/content-modeling/managing-components#create-a-nested-component), creating a parent-child relationship within a component.
For instance, you can add a call-to-action component to a page header component:

You can reuse individual components as many times as needed, even if they're already used within nested components. So you can use a call-to-action component in both a page header component and a product collection component.
With nested components, your page elements can be customized even further, providing more options for users to engage with your content. Check out our [schema docs](/content-modeling) for more tips on how to build web page layouts of any complexity with ease.
***
## Redesigned Access Tokens page for a better user experience
*June 5th, 2023*
We’re excited to introduce a redesigned Access Tokens page in Prepr to bring you a more user-friendly and intuitive experience.
With this update, you will be able to view the [permissions](/graphql-api/authorization#permissions) granted to tokens, as well as which token is currently in use in the [API Explorer](/graphql-api/test-queries). This will help you keep track of your tokens and ensure that you are using the correct one for your needs.
In addition, we have also added a new feature that notifies you when a new access token becomes available. You will see the notification as an information badge on your existing token. It will help you stay up-to-date and have access to the most recent [API features](/graphql-api/upgrade-guide).
Also, on the Access Tokens page, you can now copy the image and file domains to use them in your front-end framework add-ons, such as Nuxt Image, if needed.

If you have any feedback or suggestions for further improvements, please let us know in the [Slack channel](https://slack.prepr.io/) or by [contacting Support](https://prepr.io/support).
***
## Option to restrict a user role by locale
*May 23rd, 2023*
With this update, we've added a new feature that lets you manage user role permissions at a more granular level.
You can now define the locales to which a specific user role has access. This is especially useful for those who work with a multi-language setup in Prepr and need to ensure that certain users have access to specific locales. For example, you can restrict a marketer of your Belgian brand to accessing only content in the nl-BE and fr-BE locales.
To use this feature, [create a new role](/project-setup/managing-roles-and-permissions#add-or-edit-roles) and enable the *Content* permission. Then, select the necessary locales that the user role should have access to. If you want this user role to access content items of all locales, you can leave the field empty.

***
## Option to include a country, language, and optional fields in a slug template
*May 22nd, 2023*
When [adding a slug to a model](/content-modeling/field-types#slug-field), you can define which fields are used for slug generation. This update extends the list of available fields, making it easier to identify and memorize content item URLs.
In addition to the existing *title*, *id*, and *locale* fields, you can now include the following:
- *country* – adds the country code for a locale, such as *DE* for de-DE and *FR* for be-FR.
- *lang* – adds the language for a locale, such as *de* for de-DE and *be* for be-FR.
Also, the slug generation has become more flexible for slugs with multiple fields. If any of these fields are not required in a model, a slug can still be generated without those values. In other words, making a field optional in a model allows the field to be omitted when generating a slug.
For example, if the slug template equals *`{title}/{authors.slug}`* and the author is not set, then the generated slug will only be the title value.

***
## UX improvements for Environment settings
*May 17th, 2023*
As part of our ongoing efforts to improve user experience in Prepr, we have introduced several updates to environment settings. The changes include:
- *General environment settings* were moved from the organization level to the environment level. This means you can now rename your environment and change its timezone and language settings with fewer clicks. Read more about [environments in Prepr](/project-setup/setting-up-environments).

- *Locales settings* were moved to a dedicated page for quick access to a multi-language setup. Here, you can choose available locales for your environment and set a default. Learn more about [content localization with Prepr](/content-management/localizing-content).

- The *Apps* page was renamed to *Integrations* to better reflect its functionality. Here, you can connect your Prepr to a chosen 3rd party service. Explore available [integrations in Prepr](/integrations).
***
## Sign up to Prepr with your GitHub and Google accounts
*April 28th, 2023*
You can now use your GitHub or Google accounts to [create a new Prepr account](https://signup.prepr.io/) or log in to an existing one. This makes the sign-up process quicker and more convenient for you.
Don't miss out on the opportunity to streamline your account creation process and start exploring all that Prepr has to offer.

***
## Expanded range of languages for content creation
*April 26th, 2023*
Prepr has expanded the range of available languages with 41 new locales, including second languages of many countries. This provides editors with a greater choice when creating content for audiences around the world. No matter where your readers come from, whether it's Brazil, Italy, Norway, or Greece, they can find content that truly resonates with them.
To learn more, please [refer to our localization docs](/content-management/localizing-content) and check out the full list of available locales in your Prepr environment settings.
If you need a specific locale that is not listed, please [contact our Support Team](https://prepr.io/support), and we will add it upon request.

***
## View your Prepr content on the Patterns site
*April 26th, 2023*
We are happy to announce that you can now view a live website based on imported demo data, without writing a single line of code. Follow these steps below to view your content on the site:
- After you have created an environment, choose to **Load demo data**.
- Click the **View site** button. A new window will open and show the *Patterns site*.
- Edit or add content for web pages, articles, live stream events and even a navigation with menu items using the imported models and components. Your content will be visible on the site in realtime.
You are most welcome to clone and edit the Nuxt.js repository if you'd like to change the schema and see the results on your own localhost. You can also deploy the site using Vercel with just the click of a button.
We’d love to hear your feedback on this feature through the [Prepr Slack channel.](https://slack.prepr.io/)


***
## GraphQL API update
*April 17th, 2023*
The following updates to the GraphQL API help to keep queries clean and adds support options for analytics and SSR when using personalization and A/B testing. There is also a speed improvement especially for customers with complicated content models.
- Added new field `_context` to models and components in a Stack. See the [API system fields](/graphql-api/schema-system-fields#personalization-and-ab-testing) and the [API reference docs](/graphql-api/personalization-recommendations-personalized-stack) for more details.
***
## Personalize content for 3rd party customer segments
*April 7th, 2023*
Delivering personalized experiences with Prepr has become even more accessible. You are no longer limited to customer segments created by Prepr when personalizing content. Now you can use segments maintained in any CRM or CDP system of your choice without importing customer data into Prepr.
To use this feature, provide a *Segment reference ID* copied from your external system when [creating a new segment in Prepr](/personalization/managing-segments#use-external-segments-from-crmcdp-systems). Once you've personalized your content, call the API, passing the `Prepr-Segments` header in your API request. Read more about [using external segments for content personalization](/personalization#segments-from-external-crmcdp-systems).

***
## Improve Prepr content searches with Algolia
*March 30th, 2023*
We’re happy to announce that you can now integrate Prepr and Algolia to provide users with fast and flexible searches across your web app content.
Setting up the Algolia integration in your Prepr is easy. With just a few clicks, you can connect Prepr to your Algolia application, and Prepr will handle the rest automatically.

Once Prepr is connected to Algolia, it sends your content item data to Algolia. Whether you publish, update, or delete a content item, all the changes will be reflected in real-time in your search index via the Algolia Search API. This ensures that your users receive the most up-to-date search results.
For detailed instructions on integrating Algolia, please refer to the [Algolia integration guide](/integrations/algolia).
Please note that the Algolia integration is a paid option on top of your regular subscription and needs to be activated upon request. For more information, please [contact our Sales team](https://prepr.io/contact-sales).
***
## Introducing Dark Mode for Prepr
*March 30th, 2023*
We’re excited to announce that Dark Mode is now available in Prepr. So you can enjoy all the same functionality with your preferred appearance.
When designing and developing dark mode, we focused on refining all UI elements for their color and contrast to help reduce eye strain and provide a comfortable viewing experience to our customers.
- **Colors:** We use dimmer background colors and brighter foreground colors to ensure the interface has sufficient contrast.
- **Text and Icons:** We display the text and icons in a contrasting color on a dark background to maintain high text legibility and image visibility.
You can switch between dark, light, and system modes anytime. Hover over your Prepr profile icon and pick your preferred display setting.

***
## Upgraded model templates
*March 28th, 2023*
We are pleased to announce that we upgraded our model templates when you create a model. Now, it's even easier to set up commonly used patterns in Prepr such as *Page*, *Blog*, *Live stream*, *Navigation*, and *App config*. All you have to do is create a model and choose the pattern template. Prepr will then create the models and components that you need automatically. If the template you choose doesn't completely fit your needs, simply update the models and components according your requirements.

***
## A/B testing update
*March 23rd, 2023*
As part of our ongoing improvements on existing features in Prepr, we bring you an update to the A/B testing feature. Now, it's even simpler to do A/B testing and you can A/B test parts of a content item instead of the whole content item. This is possible by using the *Stack field*. Check out the [stack field doc](/content-modeling/field-types#stack-field) for more details.
Simply click the A/B test icon on the element in the stack, which could either be a content item or component. Duplicate the element and update the copy to create a Version B of the element.
You can also run an A/B test with a single item. In that case, 50% of your users will see the selected item and the other 50% won’t see it.

***
## Sync two versions of a schema
*March 10th, 2023*
It is now possible to sync schemas between two environments in the same organization at the click of a button. This is useful, for example, if you have the most up-to-date version of your schema in the production environment and you want the schema version in the development environment to be updated to do testing with more realistic test cases.
Check out the [Sync schema docs](/development/working-with-cicd/syncing-a-schema) for more details.

***
## Delete a language variant of a content item
*March 8th, 2023*
With this update, Prepr now offers an additional level of flexibility in managing content items. Content editors can now choose to delete the entire content item or a specific language variant. This is particularly useful when you need to remove unwanted content from only one locale without affecting the entire web app.
[Click to delete a content item](/content-management/managing-content/managing-content-items#delete-a-content-item) and then choose a preferred option:

***
## Content item sidebar configuration
*March 6th, 2023*
We are happy to give you more control to help your content editors. You can now set up additional sidebar settings for content items. For example, if you want to skip reviews for some types of content items or publish them right away when saving. The following new options are available when you create or edit a model:
- *Workflow:* If you disable this option, the *Status* and *Assignee* won't show up on the sidebar and content editors will directly publish a content item when they save it.
- *Scheduling:* This option lets you choose whether or not content editors can schedule content items for publishing or archiving.
- *Engagement insights:* This option lets you choose whether or not content editors can see engagement analysis in the sidebar.
- *Commenting:* If you enable this option content editors can view and make comments for the purpose of reviewing content items.

***
## Add subtitles to your Mux video assets
*February 21st, 2023*
You can now easily add subtitles to your Mux videos in Prepr to provide multilingual support to your web app visitors and extend the web app accessibility.
To add subtitles, navigate to the needed video file in your *Media Library*, click **+Add Subtitle**, choose a locale, and upload either an *SRT* or *WebVTT* file containing the subtitle information. Prepr will automatically generate a subtitle URL and add it to the video in Mux.

There's no limit on the number of subtitle files you can include in your video asset. Each subtitle file will be stored as an individual file asset in Prepr.
[Learn more about video assets in Prepr](/development/best-practices/assets/video-audio).
***
## Stack field with personalization
*February 13th, 2023*
We are excited to announce the release of the *Stack field*. A stack field is a field in which you compile a 'stack' of content items and components. This new field makes it much easier to structure and compose your component-based web pages. When you add this field in your models, you can combine content items and components in a single step when composing the content.
The personalization process has also been streamlined and made more flexible. Now you can personalize items and components based on [customer segments](/personalization/setting-up-personalization) or countries within a content item. For example, set up the stack as follows:
- In your schema, add a stack field to your page model and allow the applicable components and items to be added.
- Add components or items to your page stack such as page headers and CTA's.
- Finally, add segments and countries to personalize the components and items within your stack.
Check out the [page pattern](/content-modeling/examples/page) doc on how to use a stack field and the [personalization](/personalization/setting-up-personalization) step-by-step guide for more details on setting up personalization within the stack.

Also, Prepr has developed an automatic migration tool that allows upgrading the *Content reference* field to the *Stack* field without needing to change the front-end setup.
You will see the **Upgrade to Stack field** button next to the content reference field if it exists in your schema. The **Upgrade to Stack field** button will only appear for a *Content reference* field with the *Modal* appearance setting.

***
## Embed Apple Podcast in your content item
*February 13th, 2023*
As of today, it is possible to use Apple Podcast as a social embed in Prepr. Choose Apple Podcast as a social field, or as an element in your dynamic content field.

Add the URL of a podcast and Prepr generates a preview in real-time.

***
## Updated permission scopes for GraphQL access tokens
*February 8th, 2023*
Now you can define a permission scope per GraphQL access token more granularly. The new approach lets you choose which content item statuses are accessible for an access token. For example, you may want to get items that are still *In progress* or under *Review*.
You can see the full permissions list in the screenshot below:

Additionally, you can manage the GraphQL introspection setting. Disable it to prevent unauthorized users from accessing your schema, including types, fields, and queries.
***
## Improved usability for setting up content references
*January 4th, 2023*
We’re introducing a new design of the *Content reference* field in the Schema Editor and on the Content item page to make it easier to combine multiple content items on a single webpage.
When you select allowed models, you can now choose whether editors are allowed to create new content items or not and whether to include content items from other environments for these specific models. So you get more flexibility with less effort. Check out the new options in the screenshot below.

We've also updated the look and feel of the Content reference field in content items when the Modal with search appearance type is selected. Instead of selecting create/search item first, editors now choose the model first to see a filtered list of content items. If the needed item is not present, editors can create it there and then.

***
## Improved 3rd party content integration
*January 4th, 2023*
With this update, we’re introducing *Remote Content* – an improved workflow for using 3rd party content in Prepr content items, for example, products from an e-commerce platform or job postings from a backend system.
The setup process has become more convenient and faster thanks to our [new advanced *Schema Editor*](/changelog#release-of-a-new-schema-editor). You can now [set up a remote source](/content-modeling/setting-up-a-built-in-remote-source) and add it to the desired model within a single interface.

To get started, check out our [Integrations guides](/integrations).
Source: https://docs.prepr.io/stay-updated/changelog2023
---
# Changelog 2024
Find the beautiful features and important updates that were added to Prepr in 2024.
This changelog gives you an insight into the most eye-catching releases during this period.
[Latest](/changelog) | **2024** | [2023](/stay-updated/changelog2023)
## Introducing new embeds for Bluesky and Threads
*December 23th, 2024*
As requested, we're pleased to bring you two new embeds in your content: Bluesky and Threads, two rapidly growing social networking platforms.
These embeds allow you to enrich your content with real-time updates from these platforms.
By leveraging embeds from Bluesky and Threads, you keep your content relevant and make your content more appealing to web app visitors.
Check out the [creating rich content doc](/content-management/managing-content/creating-rich-content#the-dynamic-content-editor) for more details.
## Prepr now supports Vercel Content Link
*December 17th, 2024*
We’re excited to announce that Prepr now supports *Vercel Content Link*.
This feature allows you to edit website content directly from your preview website.
By enabling *Edit Mode* via the toolbar, users can simply hover over elements to reveal links that open the corresponding item for quick updates — no developer needed.

Check out the [Previewing doc](/project-setup/setting-up-previews#vercel-content-link) on how to activate the Content Link.
## New HubSpot integration: Adaptive content for HubSpot segments
*December 16th, 2024*
The new HubSpot integration allows you to create segments in Prepr based on HubSpot lists.
Once this integration and relevant segment is set up, Prepr automatically adds the known HubSpot contact to the appropriate segment when they visit your website.

Your website can then render adaptive content for this visitor. Check out the [segments docs](/personalization/managing-segments) for more details.
This integration is useful when HubSpot is a source for your segments, such as for specific campaigns or segments based on leads.
This means you can seamlessly leverage these existing segments to deliver adaptive content directly in your website.
Enhance your engagement strategy by providing adaptive content for contacts from HubSpot campaigns.
Check out the [HubSpot doc](/integrations/hubspot) on how to activate the integration.
## Adding time filters to event conditions in a segment
*December 16th, 2024*
As part of our ongoing efforts to enhance the adaptive content features, we've extended the segment event conditions with a time filter.
Now you can add a time filter when adding an event condition to target customers who interacted with specific pages.
For example, to segment customers who visited a landing page in the last month.

This precise segmentation allows you to identify and engage with customers based on their recent activity or interest.
By leveraging these insights, you can improve engagement and conversions by targeting the right audience at the right time.
Check out the [segments doc](/personalization/managing-segments#time-filter) for more details.
## New Day and Time context filters in segment designer
*December 16th, 2024*
We're happy to announce an extension to the segment designer context selection.
You can now choose one or more days or times when customers visit your website.

Creating segments with these filters allow you to target customers with special time-specific or day-specific content such as discounts/promotions.
For example, offering discounts to customers who make purchases on the weekend.
Check out the [Segments doc](/personalization/managing-segments) for more details.
## Improved media browser
*December 13th, 2024*
We’re happy to introduce a new workflow for adding assets to content items with an improved media browser.
When you add assets to content items, you now have the option to drag and drop an asset directly into your content item.

Other than the clearer asset upload options, you'll notice more intuitive image cropping.
This streamlined process allows you to manage assets directly while editing your content, making everything faster and easier.
We've cut out all the extra clicks, letting you focus more on your core tasks to create impactful content.
Check out the [assets doc](/content-management/managing-assets/editing-and-configuring-assets) on how to edit and configure assets in your content items.
## New GraphQL API version 2024-12-05 is available
*December 5th, 2024*
The GraphQL API has been updated with the following additions:
- There is a new default `_json` field in the Remote Source type that contains the raw data content for the remote source.
- The API now supports single-item Remote source fields.
- It also supports two new embed types, `BlueskyPost` and `ThreadsPost`.
- The API allows you to filter *Stack* fields in a model by the *Typename* of a component in the stack.
Check out the [GraphQL API upgrade guide](/graphql-api/upgrade-guide#version-2024-12-05) for more details.
## New HTTP header context in the segment designer
*December 5th, 2024*
Once again, we bring you an update based on your feedback: The new *HTTP header* context option in the segment designer.
You can now segment customers based on a context related to the web app that customers use.
For example, to display specific content to customers based on the app version they're using.
This means you can deliver precise content, such as version-specific content, to customer segments, supporting seamless feature rollouts or phased updates.

Check out the [segment designer docs](/personalization/managing-segments) for more details.
## Update existing content items when adding fields
*December 2nd, 2024*
We're excited to bring you a new option to streamline your workflow when adding new fields.
Now, when you add a *Text*, *Number*, *Boolean*, or *List* field to a model and set the **Initial value**, Prepr allows you to update all existing content items with one click.

You no longer need backend scripts to bulk update the related content items when adding new fields to a model.
This feature not only saves you time but reduces the risk of missing content and potential site issues.
For more details, check out the [field types doc](/content-modeling/field-types#text-field).
## Reassigning a duplicate content item
*November 19th, 2024*
As requested, we've made creating similar content items even more efficient.
From now on, when you duplicate a content item, it's automatically assigned to you.
This also means no more unnecessary notifications for others.
For more details on editing content check out the [Managing content items docs](/content-management/managing-content/managing-content-items).
## New Segment Designer
*November 8th, 2024*
We’re thrilled to introduce the new *Segment Designer*, a major product update shaped by your feedback on the Prepr personalization feature.
The *Segment Designer* helps you segment your audience with greater precision, improving visitor experiences that lead to higher engagement and conversions.

Now when you create customer segments, you can set up more precise conditions, and define a current context for the segment.
The *Context* of a segment includes current info about the customer, like the device they're using or the country they're in, when they interact with personalized content.
To align with the new *Segment Designer*, we've made some minor updates when you add *Adaptive content* to a content item.
The *Country* selection based on a visitor's geolocation has been removed. You can now set this up in the *Context* of the segment instead.
These changes ensure that your segments in the Adaptive content are consistent with the segments that you've built.
Let's take a look at new features in more detail:
- Logical operators
Previously, multiple conditions in the same segment were processed as mutually inclusive (AND), so it was more difficult to set up independent conditions for the same segment.
Now you can explicitly choose the logical operators `AND` or `OR` to combine conditions exactly the way you need them.
- Streamlined UI for easier segmentation
The *Segment Designer* has a more intuitive design that makes it easier for you to build segments.
As you set up conditions, they now form clear, logical sentences making it easier to see exactly which groups of customers are included in your segments.
- New filter options
- *Event frequency:* Segment customers who, for example, viewed a page more than three times.
- *Event with content reference:* Target customers based on a referenced content item, such as an article by a particular author.
- *Event for specific models:* Create segments for customers who viewed types of content like blog articles.
- *Previous session:* Segment based on customers who last visited within a specific time frame, like the past 30 days.
We're confident that this update makes segmenting your audience much simpler and more intuitive, while giving you the option to be more precise with your personalization.
For more details on how to build customer segments, check out the [Segments doc](/personalization/managing-segments).
If you have more suggestions on how we can simplify your experience with Prepr, [we'd love to hear from you.](https://docs.google.com/forms/d/e/1FAIpQLSf2kANsW0MRMOsETQVE5Ac6ikVyJqz7Zi7yes86aKaC9oFf5w/viewform?usp=pp_url)
## New visual model and component selection
*October 28th, 2024*
Great news for content editors! The new visual model and component selection solves the following challenges when adding content to your web pages:
1. Many components have technical names, like a *Call to action* component.
2. The list of content items and components is often very long for you to scroll through.
Now when you choose a content item or component in a stack or reference field, you'll see a visual preview of what your content item or component could look like.
You can also easily find content items or components by a tag which shows you a logical grouping, such as *Articles*.

We trust that you'll enjoy this more intuitive selector that boosts productivity when editing content.
To make the preview images and tags available, developers can upload preview images and define relevant tags, where needed, directly in the model or component settings.
Check out the [model settings](/content-modeling/managing-models#appearance) or [component settings](/content-modeling/managing-components#appearance) for more details.
## New dwell time metric
*October 15th, 2024*
We are excited to introduce the new dwell time metric for your A/B tests and adaptive content.
Until now, you could only track their results with surface-level metrics such as the number of impressions and conversions.
While these metrics provide good insights into visitor behavior, in some cases you need a better insight into user engagement of some elements on a page, especially when you're not tracking any clicks.
With the new dwell time metric, you can track the average amount of time that customers view a specific element on a page, giving you this deeper insight.
When used in A/B testing, dwell time allows you to compare the effectiveness of different versions of content.
For example, if variant A of a *Product description* holds the user’s attention for an average of 45 seconds, while version B only captures 20 seconds, it's obvious that variant A is more effective.

Check out the [A/B testing guide](/ab-testing/running-ab-tests#evaluate-the-ab-test) or the [Adaptive content guide](/personalization/managing-adaptive-content#evaluate-the-personalized-variants) for more details.
## New GraphQL API version 2024-10-04 is available
*October 4th, 2024*
The GraphQL API has been updated to support the single-item [*Stack*](/graphql-api/schema-field-types#fetching-a-single-stack-field) and [*Content reference*](/graphql-api/schema-field-types#fetching-a-single-content-reference-field) fields.
It also includes a change to retrieving an A/B test with only an A variant.
A/B tests without a B variant will now return no element for B targeted visitors, instead of defaulting to A.
Check out the [GraphQL API upgrade guide](/graphql-api/upgrade-guide) for more details.
## Filter assets by enumeration values
*October 1st, 2024*
You can now filter your assets by specific enumeration values, making it even easier to find the ones you need.
For example, filter assets by an enumeration field *License holder* to find videos or images that belong to certain companies.

This enhanced filtering allows you to quickly and easily locate the assets you need, boosting your productivity.
Check out the [managing assets doc](/content-management/managing-assets/managing-assets#finding-assets) for more details.
## Choosing a component title
*September 27th, 2024*
Normally, the title of a component in a *Stack* or *Dynamic content* field is set to the first text element in your component.
But, based on your feedback, we’ve made things a bit more flexible.
At times, you may want the component title to be the title of a referenced content item.
For example, when the embedded component title should be the headline of an article.
Also, a component might just have a *List* or *Number* field, and in those cases, you might want the component title to be the chosen list item value or the number entered.
For example, a number of the item that defines its order in a list.

As a developer, you now have the option to set the component title to these values instead, giving you more control and flexibility.
This means the content editor sees clearer and more meaningful component titles in their content, making their content more understandable at a single glance.
Check out the [components doc](/content-modeling/managing-components) for more details.
## Single content reference field and single stack field
*September 19th, 2024*
As a developer, you can now configure a single content reference field and a single stack field.
This setting limits the content editor to adding just one referenced content item to a content reference field
and just one referenced content item or component to a stack field.
For example: If an article should only have one author.

If you change a content reference or stack field to a single type, you'll get a warning to change existing queries in your front end.
The single, flat structure reduces data complexity, making API queries faster and simpler.
This means improved performance and quicker data retrieval, so you can focus on building with less overhead.
Check out the [API field types doc](/content-modeling/field-types#content-reference-field) for more details.
## Choosing your own conversion event
*September 18th, 2024*
Until now, your metrics data for *Adaptive content* and *A/B testing* was based on the `click` event.
With this update, you can now choose the event which represents conversions for you.
Check out the [A/B testing doc](/ab-testing/setting-up-ab-testing#add-html-attributes-to-track-impressions-and-conversion-events) on how to send your conversion event to Prepr, such as a custom event for quote requests.
With the new event filter in the metrics modal, you can choose to view metrics by the conversion event that matters to you.

This means you’ll be making optimization decisions based on even more precise and relevant data, helping you drive better results.
## Introducing Bitbucket Schema Sync
*September 13th, 2024*
In addition to the *Direct*, *GitHub*, and *GitLab Schema Sync* options, you can now choose to sync the schema using Bitbucket.
If your preferred tool is Bitbucket, you have control over the sync process to manage schema updates exactly the way you need.

Check out more details in the [syncing a schema doc](/development/working-with-cicd/syncing-a-schema).
## New Technical contact role
*September 11th, 2024*
With the new *Technical contact* role, you can add your technical admin team members to Prepr.
They can then be contacted directly for any incidents related to failed webhooks, or remote sources that are not syncing.
Any announcements from the Prepr status page will also be emailed to them automatically.
This means a quicker collaboration and response to solving incidents.
Check out the [roles and permissions doc](/project-setup/managing-roles-and-permissions) for more details.
## New help text display option
*September 10th, 2024*
We’ve added a new way to show help text in content items.
Instead of displaying the help text in small font below each field, you can now have it appear as a tooltip when editors hover over the icon next to the field name.

This option makes longer help text more readable and keeps content items uncluttered.
Content editors can quickly check the help text when they need it, without it getting in the way.
## Overview of linked content items
*September 10th, 2024*
We've added a new sidebar option to the content item detail page that shows where this content item is referenced.
You can now easily find and view linked content items.
When you try to delete a content item that is referenced in other content items, you'll get a warning about the linked items.
This means you can avoid broken pages when deleting a content item with linked items. For example, find all articles linked to a specific author from their detail page.

## New content view: Adaptive content and A/B tests
*September 9th, 2024*
With more users adding A/B tests and adaptive content in Prepr, and thanks to your valuable feedback, we've introduced a brand-new view to the content items overview page. Now, you can easily see all content items with adaptive content and A/B tests at a glance.
It’s faster and simpler to find exactly what you're looking for.
You can also filter this view further by the **Status** (*Active* or *Inactive*), **Type** (*Adaptive content* or *A/B test*), the content item **Model**, and the **Language**.

Check out the [content items doc](/content-management/managing-content/managing-content-items#content-views) for more details.
## Block AI bots from scraping assets
*September 5th, 2024*
We've implemented an update to block all AI bots from scraping your video and document files from Prepr *Media*. This reduces the amount of bandwith you use.
If you want to enable access to that content for those bots, ask the Prepr account owner to [contact our Support Team](https://prepr.io/support) to enable this.
## New API option to open files in the browser
*September 5th, 2024*
When you request files in a GraphQL API query, they are downloaded by default.
With this update, you can now include a URL argument, `inline` with a value of `true` to display the file contents in a browser instead.
This means that you get the file exactly the way you need to deliver it to your visitors.
Check out the [GraphQL docs](/graphql-api/schema-field-types#files) for more details.
## Organize your enumerations into schema folders
*August 27th, 2024*
It's now possible to organize your enumerations into folders like you can with models and components.
When you have dozens of enumerations, these folders make it easier to find related enumerations instead of scanning a long alphabetical list.
For example, when you have multiple enumerations needed for the same components.

Check out the [enumerations doc](/content-modeling/managing-enumerations#organize-enumerations-into-folders) for more details.
## Exclude IP addresses from data collection
*August 27th, 2024*
We've added a feature in the event tracking settings that lets you exclude specific IP addresses from data collection. This helps you maintain the integrity of your analytics by ensuring that actions like impressions and clicks from those IPs are not tracked. By filtering out internal traffic, you can keep your data clean, which is crucial for accurate AB testing and decision-making.

Check out the [collect event data docs](/data-collection/setting-up-the-tracking-code#excluding-ip-addresses) for more details.
## Filter content items by enumeration values
*August 26th, 2024*
You can now filter your content items by specific enumeration values, making it even easier to find the items you need.
For example, filter *Product* content items by the *Size* to find large T-shirts.

This enhanced filtering allows you to quickly and easily locate the content you need, boosting your productivity.
Check out the [filter content items doc](/content-management/managing-content/managing-content-items#filter-content-items) for more details.
## Schema sync upgrade
*August 22nd, 2024*
We've upgraded the *Schema Sync* and added the *GitLab Schema Sync*.
With the improvements to the Schema Sync process, you'll see better error handling and can now preview changes before completing the sync.
In addition to the *Direct Schema Sync* and the *GitHub Schema Sync* options, you can now choose to sync the schema using GitLab.
This upgrade gives you more control over the sync process to manage schema updates exactly the way you need.

Check out the [Schema sync doc](/development/working-with-cicd/syncing-a-schema) for more details.
## Improved schema import and export processes
*August 22nd, 2024*
As part of our continued efforts to improve existing Prepr features, we've updated the import and export of models and components.
The import and export logic has been updated to match the *Direct Schema sync* process to ensure consistency of models and components during the individual import/export processes.
In addition to this improvement, it's now also possible to import and export individual enumerations and remote sources.
When you only want one or a couple of enumerations or remote sources created in a test environment then you no longer have to create them manually.
The improved import and export keeps your data structure intact.
This means your schema integrity is maintained even when importing complex models or components with embedded elements and reference fields.
This, in turn, means more accurate testing. For more details, check out the [Schema docs](/content-modeling/managing-models#export-and-import-a-model).
## User management updates
*August 22nd, 2024*
We've made some improvements to the user management feature. In particular, the following updates are now available for Agency users:
- 2FA is now required for added security when managing client environments.
- Agencies now have to manage permissions for agency users at agency account level. It’s no longer possible to manage agency users at the organization or environment level.
- Agencies can now create their own custom roles that can be used in all client environments.
- Permission to view the audit logs are now available to all agency accounts.
The updated user management improves control for agency users, provides better oversight and gives more flexibility when managing their client users and permissions.
Check out the [manage users doc](/project-setup/managing-users#agency-accounts) for more details.
## Introducing Metrics for A/B Testing and Personalization
*August 6th, 2024*
Prepr is a headless CMS with A/B testing and personalization features. Until now, it was only possible to measure A/B testing and personalization in external analytics tools.
Based on feedback from our customers, we've implemented the option to track impressions and conversions to help you determine the results of your optimizations.
Now you can see these results directly in Prepr.
This means you gain insights into the impact of your experiments quickly and easily without needing other analytics tools. You can then use these insights to continuously improve customer satisfaction and conversion rates. Moving from biased design decisions to fact-based design decisions.
It's now possible to set up your front end to send data to Prepr for metrics.
For more details on how to set up your front end to trigger metrics calculations in Prepr, check out the [A/B testing doc](/ab-testing/setting-up-ab-testing)
or the [Personalization doc](/personalization/setting-up-personalization).
When metrics data is available you can view the results from your A/B test or personalization group.
You can then filter the results by a chosen date range (defaulted to the last 90 days)
or by a chosen segment in the case of A/B testing. The following metrics data is available:
- Number of impressions
- Number of conversions
- Conversion rate
- Standard error
- Uplift
- Probability that a particular variant performs better than the control.
- Simple graph view of results

For details on how to intepret the metrics, check out the [Run A/B tests doc](/ab-testing/running-ab-tests) or the [Personalize website doc](/personalization/managing-adaptive-content).
The Metrics feature can be used successfully from GraphQL API Version 2023-04-17. If you have an older GraphQL API version, check out the [GraphQL API upgrade guide](/graphql-api/upgrade-guide#how-to-upgrade-to-a-newer-graphql-api-version).
If you have more suggestions on how we can simplify your experience with Prepr, [we'd love to hear them!](https://docs.google.com/forms/d/e/1FAIpQLSf2kANsW0MRMOsETQVE5Ac6ikVyJqz7Zi7yes86aKaC9oFf5w/viewform?usp=pp_url)
## New Settings for A/B Testing and Personalization
*August 6th, 2024*
We're happy to announce new settings available for your A/B tests and personalization.
Previously, each A/B test variant was shown to 50% of customers.
It's now possible to modify the percentage of traffic allocated to each variant during an A/B test.
This means you can optimize your experiments for more accurate results. So, it ensures faster decision-making.
Check out how to manage this setting in the [A/B testing guide](/ab-testing/running-ab-tests#manage-the-ab-test).

Previously, a query for a content item with personalization only returned the first matched personalized element.
It's now possible to enable the API to return all the matching personalized elements instead.
For example, when there are multiple FAQ items that include the same segment.
This allows you to choose which personalized elements are shown in the front end, meaning more relevant content.
Check out how to manage this setting in the [Personalization guide](/personalization/managing-adaptive-content#manage-the-personalization).

## New SEO field options for components
*August 5th, 2024*
Previously, you could only set model text fields as SEO titles or meta descriptions.
Now, you can mark text fields in components as SEO titles or meta descriptions, like you can in models.
This means you can manage your SEO attributes consistently across your schema.
In so doing, you improve the visibility and ranking of your content more efficiently, leading to better search engine performance and increased web traffic.

Check out the [Text field doc](/content-modeling/field-types#item-title-and-seo-fields) for more details.
## Disable content item deletion
*August 5th, 2024*
Based on your feedback, we've added a setting that disables content item deletion for a model. When active, this setting prevents editors accidentally deleting content items.
Now you don’t have to worry about content editors removing content items that store important system information, such as *App configuration* like global meta tags and copyright info.

This update makes working with Prepr even smoother. If you have more feedback on how we can simplify your experience with Prepr, [we'd love to hear from you!](https://docs.google.com/forms/d/e/1FAIpQLSf2kANsW0MRMOsETQVE5Ac6ikVyJqz7Zi7yes86aKaC9oFf5w/viewform?usp=sf_link)
## New Billing role
*July 16th, 2024*
A new default user role, Billing, is now available. This role grants access to the organization's plan and billing information, enabling users to manage payment details, view and handle invoices, and oversee subscription details. Billing users do not have access to other administrative or content-related functions within the environments or organization.
For more information on the new Billing role and its capabilities, please refer to our [updated documentation](/project-setup/managing-roles-and-permissions).
## Improved access token management
*July 16th, 2024*
As requested, we've made a couple of updates to improve the management of access tokens.
It's usually very useful to open the *API Explorer* directly from a content item to perform GraphQL queries.
By default, this API Explorer connects to the first access token when the environment was created.
Previously, you couldn't change this default access token.
With these new UI updates, you can now switch the default access token for the **Open API Explorer** button.
Also, now you can just hover over each access token to **Edit**, **Delete**, or **Use for API Explorer**.

This improvement makes managing access tokens more intuitive and efficient.
Switching access tokens ensures the API Explorer uses the most up-to-date token.
These updates give you more flexibility and control and managing access tokens is now easier and more user-friendly.
## Improving environment stage visibility
*July 10th, 2024*
Some of our customers manage multiple Prepr environments. In this situation, there are times when users accidentally make updates in the wrong environment.
That is why we've made minor UI updates to make it clearer to users which environment they're currently working in.
We've updated the environment dropdown selector and added a new label at the top of the screen to indicate which non-production environment you're currently working in.
This helps users who frequently swap between staging and production environments and reduces the risk of making updates in the wrong environment.

## Environment-to-environment Content Export
*July 5th, 2024*
We are very proud to bring you the most requested feature by developers, the *Environment-to-environment Content Export*.
With the *Environment-to-Environment Content Export*, you can easily copy content across different environments.
This streamlined process reduces your dependence on Prepr support, significantly saving time.
By maintaining current content for development and testing, you improve collaboration with marketers and editors for
more accurate testing of realistic scenarios and ensure superior quality assurance, ultimately accelerating your project timelines.
The *Environment-to-environment Content Export* goes hand-in-hand with the *Schema* sync process which should be run first to make sure that content is exported to a valid schema.
Check out the [Schema sync docs](/development/working-with-cicd/syncing-a-schema) for more details.
As a developer, you can select specific content items you want to copy over to another environment.
Trigger the content export with the **Export to** action available in the Content item list page.
You can copy content between any two environments you have access to in the same organization.
Check out the [Export content doc](/development/working-with-cicd/syncing-content) for more details on the process and troubleshooting errors.

## Introducing sharing of filtered lists with URL
*July 5th, 2024*
Sometimes, you may want to share a filtered list of content items with a team member.
However, this was previously not possible because the URL did not contain the filter parameters.
We've now added these parameters. This means you can simply copy and share the URL with your team.
This small enhancement makes collaboration easier.
## Introducing collapsible components in the Dynamic Content field
*July 5th, 2024*
We have great news for those who use components in the Dynamic Content field.
It is now possible to collapse individual or all components in dynamic content fields in your content,
reducing clutter and providing a clearer overview.
Previously a dynamic content field with a lot of components could become chaotic to manage.
Now it's easier for you to manage and focus on the specific content that needs editing,
enhancing your workflow efficiency and making the editing process more intuitive.

## Added Text Filter Option to Remote Source
*July 4th, 2024*
Upon customer request, we've added a text (`string`) filter to the list of filter options in a custom remote source.
You can now set this filter in the custom remote source feed and it'll become visible when an editor adds a remote item, allowing them to filter by text. For example, by a category name.
Check out the [custom remote source doc](/content-modeling/creating-a-custom-remote-source#step-1-set-up-your-custom-api-endpoint) for more details on how to set up an endpoint with filters.
## New heading display options in HTML fields
*July 4th, 2024*
Today, we bring you new heading display options for HTML fields.
These new options allow you to configure display options for the HTML text field headings,
by giving you the flexibility to choose which headings (`H1` to `H6`) are available to editors.

Previously, all heading options were available to editors which sometimes caused styling inconsistencies in the front end.
For example, now you can ensure that key headings, like `H1`, are reserved exclusively for article titles.
By providing this level of control, this setting supports the alignment of content with the website's design and editorial standards,
enabling more effective content management.
Check out the [Text field doc](/content-modeling/field-types#text-field) for more details.
## New component display option
*July 2nd, 2024*
Based on the results from our user research, we've implemented new component options that define how component fields are displayed in a content item or in another component. You can now choose to display component fields grouped or ungrouped in content items.

Previously, the display of component fields were always grouped with the name of the component at the top of the group. For some components, it's cleaner and avoids confusion by displaying the fields like any other content item field.
Now you can display component fields seamlessly with other content item fields. For example: An *Image + Caption* component that has an image field and caption field.

However, an SEO component is a good example of where grouping all SEO-related fields is sensible, to differentiate them from other fields in the content item.
Check out the [Component field doc](/content-modeling/field-types#component-field) for more details.
## Content item search improvement
*June 18th, 2024*
We've implemented a change to the content item *Search* functionality.
Previously, the content item search scanned through all the text in each content item, by default.
With this change, it now does a narrowed down search on the content item *Title* by default.
This improves the quality of the search results and the performance of the search when you have thousands of content items.
It's still possible to search through the *full-text* of content items by explicitly choosing this option when you click on the search bar.
The same goes for searching on the *Slug* or *ID* fields of the content items.

## Introducing Custom Events
*June 12th, 2024*
Based on user research and your feedback on segmentation, we've implemented *Custom Events*.
Previously you could only use, capture, or track predefined events in Prepr which limited your options
and didn’t always align with your segmentation needs.
Now you can define custom events so you're completely free to set up and track the events you need.

We've also streamlined the predefined events to the list below.
- The `View` event is automatically sent to Prepr when a page load is detected by the Prepr tracking pixel.
- The `Click` event is available for an upcoming feature to create metrics for A/B testing and personalization.
- The `Like`, `Bookmark` and `Subscribe` events have built-in constraints. These events can only be recorded once per customer per content item.
- The `SignUp` event is the only event not linked to a specific content item. This event prevents the customer from being automatically deleted after 90 days of inactivity.
We trust that the custom events and predefined events cover all your needs to easily track visitors.
For details on how to track and send events to Prepr, check out the [Events doc](/data-collection/recording-events#recording-custom-events).
## New GraphQL API version 2024-06-12 is available
*June 12th, 2024*
The GraphQL API has been updated for custom events and in preparation for upcoming features:
- A new field `variant_key` to allow you to track impressions and clicks for Personalized and A/B tested components.
This key supports the upcoming feature to provide metrics for A/B testing and personalization.
- A new system field `_event` has been added to the schema. This field along with some other minor changes to the API support *Custom Events*.
The new release also includes the following changes:
- `ENUM` types can now be set to legacy mode and will be returned as a `STRING` (for existing Prepr environments).
- Improved errors for incorrect requested locales.
Check out the [GraphQL API upgrade guide](https://docs.prepr.io/graphql-api/upgrade-guide#version-2024-06-12) for more details.
## Content item list improvements
*June 4th, 2024*
Based on findings from our user research, we've implemented some improvements to the *Content items* list page that significantly enhance your experience with Prepr. Overall, we've updated the UI design of the *Content items* list page to make it more intuitive and less cluttered for content editors.
As part of these UI updates, you'll notice that the checkboxes in the first column are visible when you hover over a content item. Click the checkbox to select content items to perform bulk actions like **Delete** or **Assign to**. This makes it easier for editors who need to perform actions on multiple items.

When the editor clears the selection with the new **Clear selection** button, the column names will become visible again. In this view you can see the intuitive sorting in the *Content item Title* and the *Modified date* column headers.
Simply click the name of the column header or the arrows to toggle between ascending and descending order.
Click the icon to choose other sorting options for *Publication date*, *Scheduled date* and the *Created on* date.
You will also notice that we've made the sidebar collapsible to hide filters and avoid confusion. This means the editor can now focus on their core tasks, in other words, editing content items.

Last, but not least, we've made the hover interactive for actions per content item when you need them. Instead of clicking, a simple hover over the content item makes the actions you need available, like the **Edit** or **Delete**.

While the actions and sorting capabilities have always been available, the new UI changes make the editing experience a lot more intuitive and user friendly. Check out the [Manage content docs](/content-management/managing-content/managing-content-items) for more details.
If you have more suggestions on how we can simplify your experience with Prepr, we'd love to hear them!
## Content item workflow improvements
*May 29th, 2024*
Based on user research and your feedback, we've implemented some small improvements to content items that significantly enhance your experience with Prepr.
The most obvious change is the introduction of additional publishing options. Instead of just **Publish and close**, you can now select **Publish and stay** or **Publish and add new**. This simplifies the process of publishing your work, then continuing with the same content item or immediately starting a new one.
We've also added a convenient button at the top of a content item. This lets you cancel editing without having to scroll down to find the cancel button.

Another improvement is the clear option to remove a schedule. While this was possible before, it wasn't very obvious. We've now added a link that allows you to easily remove the schedule.

Finally, you no longer need to publish parent content items when a child item is changed. Previously, changing a linked item required you to re-publish the parent item, even if it wasn't altered. This led to unnecessary extra clicks. Now, you only need to publish the changed item and can immediately continue with other tasks.
These updates have made working with Prepr even easier. If you have more suggestions on how we can simplify your experience with Prepr, we'd love to hear them!
Check out the [Manage content docs](/content-management/managing-content/managing-content-items) for more details.
## Define your own fields for *Assets*
*May 14th, 2024*
We are very excited to bring you the long-awaited feature to add fields to Assets. It is now possible to define your own fields to keep track of asset-specific info like *Copyright* or *Source* in addition to the core asset fields for the title, description and the author.
Now, it's also possible to enable localization for your assets. This means your editors can enter information about assets in the locale that is relevant for them. This feature gives you the flexibility to create your own Asset content structure with localization and makes it much easier for the front end to retrieve additional information about assets.
This feature introduces a new **Asset** model available to any user who has access to the Prepr *Schema* or *Shared schema*.

When you enable localization on the **Asset** model, the fields in each asset will be available for all [available locales](/content-management/localizing-content).
Check out the [Asset model doc](/content-modeling/defining-the-asset-model) for more details.
## Organize your models and components with Schema folders
*May 10th, 2024*
It's now possible to organize your models and components into folders. When you have dozens of models or components, these folders make it easier to find related models or related components instead of scanning a long alphabetical list. For example, when you have multiple components which are used as section of a page.

## Speed up text editing with new AI Generate and AI Optimize features
*April 30th, 2024*
We are very pleased to bring you two new features, *AI Generate* and *AI Optimize*.
The *AI Generate* feature generates new text on request, for example, when a content editor wants to create a summary based on the main body text of an article. *AI Optimize* helps content editors to improve existing text, for example, to make their text longer, shorter or simpler. Both features make it quicker and easier for content editors to create more engaging text in their content.

Go to the **Schema** tab to set up the AI parameters for these features in the relevant *Text* fields. Check out the [*Text field* settings](/content-modeling/field-types#text-field) for more details.
## Use Frontify brand assets in Prepr content
*April 9th, 2024*
As requested, we've added a DAM integration to Prepr CMS to allow content editors to access Frontify brand assets in Prepr content. This integration gives you the benefit of ensuring that your assets are brand-compliant and allows you to maintain a single source for these assets.
With this built-in integration, it's easy to set up a connection between Prepr CMS and your Frontify account. When your request for activation has been approved, you can activate the *Frontify* app in Prepr.
Once done, content editors can include Frontify assets in their content items.

For detailed instructions on integrating Frontify, please refer to the [Frontify integration guide](/integrations/frontify).
## New locales added for `fy-NL` and `es-MX`
*March 26th, 2024*
As requested, we've added support for the Frysk `fy-NL` and Mexican Spanish `es-MX` locales. Locales can be set up in the Organization **Settings** page. This feature is available to users who have the `Owner` role or a role with the *General* `Locales` setting enabled.
For more details, check out the [localization doc](/content-management/localizing-content).
## Create cleaner schemas with Enumerations
*March 26th, 2024*
We are excited to bring you the long-awaited *Enumerations* feature. We've expanded the *Schema* so you can define your own enumerations and use them in any model or component with the *List* field. For example, when you want to define days of the week.
Until now, you had to define list values every time you added a *List* field to a model or component. Now, you only need to create an enumeration once with a set list of values and reuse this list in multiple models or components. This means that you define a cleaner schema without duplicate list definitions.

Check out the [enumerations doc](/content-modeling/managing-enumerations) for more details.
The enumerations feature is available as from GraphQL API Version 2024-03-26. To activate and use enumerations, check out the [GraphQL API upgrade guide](/graphql-api/upgrade-guide).
## Sync your schemas with GitHub for a seamless CI/CD workflow
*March 15th, 2024*
We are happy to bring you a new feature, the **GitHub sync**. Until now you could only use the **Sync schema** feature to sync one schema to another, but it's not always ideal.
The **GitHub sync** allows you to use standard GitHub functionality to sync schemas between environments. As a developer, this gives you more control over the sync process to manage schema updates exactly the way you need to.
- You can sync both ways with the GitHub pull and push requests.
- This sync not only adds items in the schema, but also removes unneeded items.
You benefit from *version control* in GitHub, namely:
- You can review the schema change history.
- And you can revert changes.
Check out the [Sync schemas doc](/development/working-with-cicd/syncing-a-schema#sync-schema-with-github) for more details on how to Sync your schemas with GitHub.

## Keep track of user activities with the new Audit log
*March 14th, 2024*
With the new *Audit log* feature, it is now possible to keep track of user activities. The *Audit log* helps developers to troubleshoot errors or inconsistencies with the schema or content. The audit log is available at the organization level and you can filter logged activities by the **Date**, **Environment**, **User** and **Resource type**.
The audit log shows you *Create*, *Update* and *Delete* actions on content items, models, components, remote sources, enumerations, webhooks, apps, users, assets, roles and segments. You can also track when a user publishes a content item and when a user executes a schema sync or GitHub push/pull sync.

Check out the [Audit log doc](/project-setup/audit-log) for more details.
## New Stage option available to create a Testing environment
*March 14th, 2024*
In our efforts to support the CI/CD process of your development team, you can now choose a **Testing** stage option when creating a new environment. This will help you adhere to best practices when managing your *Development*, *Testing*, *Acceptance* and *Production* Prepr environments. Check out [DTAP configuration options](/project-setup/setting-up-environments#set-up-a-dtap-configuration) for more details.
## Set the GraphQL API version in code
*March 12th, 2024*
When we make changes to the GraphQL API that aren't compatible with older versions, we release a new one with a specific date. By default, the API uses the default version associated with your access token. However, in response to customer feedback, you can now override this version using the 'Prepr-Version' header. For more information, refer to our [Versioning & Upgrade Guide](/graphql-api/upgrade-guide).
## More flexibility with new remote source features
*March 4th, 2024*
We bring you new remote source features in our ongoing endeavor to advance our existing functionality. The new features listed below give developers more control to manage remote sources more flexibly.
- **Filters**
Now you can enable filters for content editors to find remote items easier like in the example below.

Check out [the custom remote source doc](/content-modeling/creating-a-custom-remote-source#step-1-set-up-your-custom-api-endpoint) for more details on how to set up an endpoint with filters.
- **New remote source actions**
Go to the remote source and click the icon to see the new remote source actions.

- **Resync remote items**
As a developer, you can now manually resync the items from a remote source. Prepr automatically resyncs remote source items when the `changed_on` date has been modified, but there are times when you need to resync the items on demand. This way, Prepr CMS is updated and the front end is up to date with current remote items.
- **Activate**
It is now possible to activate the remote source. This is useful when the API endpoint URL is no longer valid or the external source system is updated and no longer matches the endpoint definition. To resolve errors in these situations, the remote source will be deactivated until the issues are fixed. Once fixed, click **Activate** to reactivate the remote source.
- **New remote source field settings**
- **Set as Title** and **Set as Image**
It is now possible to specify the `Title` and the `Image` when defining the fields in your remote source. Prepr uses these settings to display the Title and image for content editors to identify items from the remote source more easily.
- **Make visible when searching for remote content**
You can also choose which of the fields in the endpoint should be made `Visible` to the content editor. In the field settings, open the **Appearance** tab to enable or disable this setting.

## Add Stack to the Dynamic Content field
*February 28th, 2024*
As you've requested, we released a new feature that allows you to add a *Stack* to the *Dynamic content* field. This new feature is an extension to the recently released [*Stack in component*](#create-better-content-structures-with-stack-in-a-component). It enables editors to create structured lists in articles that are created with the Dynamic Content field. For example, to add a list of recipes to an article about cooking equipment.
Simply enable components in the list of content types in the *Dynamic content* field and choose the components that contain a *Stack* field.

By doing this, you allow the content editor to add a component with a *Stack* field in their dynamic content. For example, they can easily add things like a list of articles to their rich text like in the image below.

## Make the most out of components by including a date field
*February 27th, 2024*
We are pleased to announce that you can now include a date field in components. Enjoy this flexibility when modeling your content, for example, in an *Event* component where the event date is an integral part of this type of content.
The date field in a component works the same way it does in a model, with the following options:
- Single or multiple Date values
- Single or multiple Date range values
- Single or multiple Date time values
- Single or multiple Date time range values
- Business hours
Check out the [Date field](/content-modeling/field-types#date-and-time-field) for details on how to set up this field.
For developers who need to make API requests, the date field in a component is available as of GraphQL version 2024-01-31.
## More accessible content with 27 new Arabic locales
*February 6th, 2024*
As requested, we've expanded the range of locales with Arabic languages. We've included 27 new countries in the list of locales, such as Egypt `ar-EG` and Morocco `ar-MA`. If you have international partnerships and customers, make your content more accessible and marketable by publishing content in their local language.
Check out our [localization docs](/content-management/localizing-content) to learn how to work with localization.

If you need a specific locale that is not listed, please [contact our Support Team](https://prepr.io/support), and we will add it upon request.
## Create better content structures with Stack in a component
*January 31st, 2024*
The long awaited *Stack in a component* feature has been released. As a developer, you can now add a Stack field to components. This means that you can create more logical, flexible, and scalable content structures for your component-based pages.
A typical example is when you need a row of buttons in a Call to action. To do this, create a *Button row* component and add a stack field to it to hold the buttons. You can then add the button row to any component you need like a *Call to action*.
[Watch the video on how to use Stack in components.](https://youtu.be/SOdw6GM0wRA)

## Enjoy a renewed Dynamic Content Editor and Content Item detail page
*January 25th, 2024*
We are happy to enter the new year with this release which promises to deliver a multitude of benefits to you as a content editor:
We implemented a new front-end framework in preparation for an upcoming release of the Live preview feature. You can now enjoy faster page loads with this update and a consistent layout when editing a content item with reference or stack fields. See below for an example of the renewed look and feel of the Personalization and A/B testing blocks in a **stack** field:

This release also includes some reworked code resulting in faster loads and an improvement to the word counter and SEO information. The deprecated **Preview** button has also been removed, but check out [the content item preview doc](/project-setup/setting-up-previews) for details on how to set up your own preview URLs.
A new *Dynamic Content Editor* has been implemented to give you a better user experience when editing lots of content at once. It's based on an established API that resolves some ongoing issues. You will notice clearer validations in the dynamic content fields, an improvement to the copy-paste function within content items and from external sources to content items, and the ability to use the Undo and Redo options.

## Make the most out of your components with the location field
*January 25th, 2023*
We are pleased to announce that you can now include the location field in components. Enjoy this flexibility when modeling your content, for example, in an *Event* component where the event location is essential for this type of content.
The location field in a component works the same way it does in a model.
For developers who need to make API requests, the location field in a component is available as of [*GraphQL version 2023-11-02*](/graphql-api/upgrade-guide#version-2023-11-02).
## Gain more flexibility with new read/write options on your fields
*January 25th, 2024*
With the release of new read/write options, you have more control over how fields are used by content editors and developers. As requested, you can now set the following new options on a field:
- Default - The field can be edited in the UI.
- Read only - The field can’t be edited in the UI, but it can be edited through the API.
- Hidden for non developers - The field is only visible for users with developer permissions.

## New Stack filter on content items
*January 22nd, 2024*
We are happy to bring you a new Stack field filter on content items in the GraphQL API and the Prepr UI. This feature makes it even easier to filter your content items. If you have content items with Stack fields that reference other content items, it is now possible to filter by these referenced content items. To add this filter in an API request, check out more details in [the reference docs](/graphql-api/fetching-filtering-collections#simple-reference--stack).

## Prepr's UI is now up to eight times faster
*January 16th, 2024*
Prepr continually strives to enhance the reliability and performance of its applications. This is our primary focus, and we are always seeking ways to improve user and developer experiences.
A recent update to our database queries has significantly improved the speed of our APIs and the UI. As a result, working with Prepr has become twice as fast since this past weekend. If you use the Mutation API, GraphQL API, and the Prepr UI in a development chain, you could experience time savings of up to eight times.
If you have any feedback on the speed improvements, feel free to respond to feedback@prepr.io.
Source: https://docs.prepr.io/stay-updated/changelog2024
---
# Shared schema
*This article explains how you can create and use a shared schema in Prepr to keep the structure of your content consistent across multiple environments in an organization.*
## Use cases
The *Shared schema* feature lets organizations use the same structure for content across different brands.
While each brand might need unique content, it's smart to use the same overall structure for all brands.
In this case, create a shared schema to use the same schema across multiple environments with a shared schema.
Another use case is managing deployments across your development, testing, acceptance and production environments.
You can create entities in your non-production environment, test them, and then promote these to a shared schema when they're ready for production.
The shared schema can then be used across the whole DTAP setup.
In all use cases, the shared schema makes development faster and easier by keeping the code base leaner and more consistent.
## Create a shared schema
To create a *Shared schema*, follow the steps below.
1. Click the environment dropdown at the top right, choose your organization and click to open the environments overview.
2. Click the **Shared schema** tab to open the shared schema page.

3. Add models, components, enumerations and remote sources to complete your schema.
Check out the [Create schema docs](/content-modeling) for more details.
When completed, each of the entities in the shared schema can be used in any environment in your organization.
## Promote entities to the shared schema
You can directly promote any model, component, enumeration, or remote source from an environment to the *Shared schema* at the organization level.
Once promoted, these entities can be accessed in any environment within the same organization.
To promote a schema entity to the shared schema, follow the steps below.
1. Go to the environment for the schema entity that you want to promote and click the *Schema* page.
2. Click the model, component, enumeration or the remote source that you want to promote to open it.

3. At the top of the detailed page of the entity, click the icon and choose the **Promote to shared schema** option.
4. If the entity has no linked entities that are not yet in the shared schema, your entity will become shared.

If you don't have the *Promote to shared schema* feature enabled, [contact our Sales team](https://prepr.io/contact-sales) for more details.
## Choose field visibility for environments
You can control field visibility per environment when using a shared schema, ideal for multi-site or multi-brand setups where fields differ slightly between environments.
To choose which environments a field can be visible for editing, follow the steps below.
1. In your shared schema, go to the relevant model or component and simply click the field to open the field settings.
2. Open the **Appearance** tab and go to the *Conditional visibility* section.

3. Select the **Show field based on environment name** option and choose all the environments where this field needs to be visible.
4. Click the **Save** button to save the settings.
Now, editors will only see this field if they're working in one of the environments you've chosen in the setting above.
Source: https://docs.prepr.io/project-setup/architecture-scenarios/shared-schema
---
# Shared content
The shared content feature supports multiple brands in an organization.
Sometimes, different brands want to share content within the same organization.
For example, each brand creates their own articles, but these articles belong to common categories.
This can be done with shared content.
To enable sharing of specific content, follow the steps below.
1. Go to the **Shared schema** tab in your organization.
2. Open the content item with the relevant content reference for the content you want to share.
3. Click the existing content reference field or create a new [content reference field](/content-modeling/field-types#content-reference-field) to a model.
and in the *General* tab, enable the toggle **Allow items from all environments**.

Check out the [Create schema docs](/content-modeling) for more details.
Source: https://docs.prepr.io/project-setup/architecture-scenarios/shared-content
---
# Blog
*This guide shows you how to model a typical blog, one of the most common patterns when implementing a web app.
Check out our [demo blog](https://acme-lease-v2.vercel.app/en-US/blog) in action.*
## Introduction
A typical blog is made up of two key web pages, an overview page and a detailed page for each blog post.
### Overview page
In the example below, you can see the overview page includes a list of blog posts with some key content.
In this example, the list includes the post title, a cover image and an excerpt of the post.
This page also includes a list of categories that you can click to filter the posts to view similar posts.
The link in each post allows the visitor to navigate to the detailed blog post page.

### Detailed blog post
In the example below, you can see more detail about a specific post, including the main content body of the post, and author information.

You can use these sample web pages as a basis when modeling the content you need in your web app.
Start by visualizing the *Post* model first.
## Post model
When modeling your content for the blog, you can start with the main model for each post, the *Post* model.
Check out the fields you can add to the *Post* model:

|Field name |Field type | Description|
|------------------|-------------|--------|
|**Title**| [Text](/content-modeling/field-types#text-field) |The title of a post visible on the web app. Required. This title can be used to query the post through the API. |\
|**Slug** | [Slug](/content-modeling/field-types#slug-field) |Part of the URL that is used to link to the detailed post page. Required. The slug is also useful as an internal field for API queries on this post. We set it to the *Title* of the post.|
|**Cover** | [Asset](/content-modeling/field-types#asset-field) |The cover image for the post. Required. Configure presets to cater for different dimensions in the web app, for example: to display the main cover in the detailed page and when displaying the image in a card.|
|**Categories**| [Content reference](/content-modeling/field-types#content-reference-field)|A reference to the [*Category*](#category) model. The category field allows the post to be grouped which can be used in the web app in different ways, for example, to filter posts by a category.|\
|**Author**| [Content reference](/content-modeling/field-types#content-reference-field)|Used to reference the [*Author*](#author) model which has content about the people who create the posts.|
|**Content**| [Dynamic content](/content-modeling/field-types#dynamic-content-field)| This field is the main body of the post and we define it to allow the content editor to include the following elements: - Heading2, Heading3, and Heading 4 - Paragraph: Allow bold, italic, and ordered list styles as well as links within the post.- Assets: For images and videos.|
|**SEO**|[Component](/content-modeling/field-types#component-field)|An embedded SEO component. This component has fields for finding this post through search engines. |
See a complete list of all other available [Prepr field types](/content-modeling/field-types).
You'll notice that some of the fields in the *Post* model are content references (link to items from another model) and components.
You can define those referenced models and components as follows:
### Author model
You can set up an *Author* field in the *Post* model. This field is a *Content reference* to a separate *Author* model.
*Author* is set up as a model to avoid duplication of person content. Check out the fields you can define in this model.
{/* The idea is that there could be content for persons with other functions and not only for article authors. For example, imagine that employees are shown in an *About us* page. The general *Person* model caters for this use case too and makes your schema more flexible and robust. */}

|Field name |Field type | Description|
|------------------|-------------|--------|
|**Name**| [Text](/content-modeling/field-types#text-field) |The name of a person. Required.|
|**Image**|[Assets](/content-modeling/field-types#assets-field)|The asset field allows the content editor to add a photo of the person to the *Author* content item.|
### Category model
You can define a *Categories* field in the *Post* model. This field is a *Content reference* to a separate *Category* model. This makes the category content reusable in the web app. For example, different posts can have the same categories.
Check out the fields you can add to the *Category* model.

|Field name |Field type | Description|
|------------------|-------------|--------|
|**Name**| [Text](/content-modeling/field-types#text-field) |The name of a category visible on the web app. Required. This name can be used to query the category through the API. |\
|**Slug** | [Slug](/content-modeling/field-types#slug-field) |Part of the URL that is used to link to this category. Required. The slug is also useful as an internal field for API queries on this category. We set it to the `{name}` of the category.|
### SEO component
You can set up the *SEO* field in the *Post* model. This field is an embedded *Component*. SEO is set up as a component because its field structure can be reused used in multiple content items from different models, namely, the *Post*, and *Page* models.

Within the *SEO* component we define the following fields:
|Field name |Field type | Description|
|------------------|-------------|--------|
|**Meta title**|[Text](/content-modeling/field-types#text-field)|The title tag. This title is the criterion for search engines to find a web page, for example. It is also the title that appears when an item is shared on social media. |
|**Meta description**| [Text](/content-modeling/field-types#text-field) | A brief description about a particular content item, for example, this description can be included in a summary view of a post in your front-end. This is also the description used when this item is shared on social media.|
|**Meta image**| [Assets](/content-modeling/field-types#assets-field) | This image is used when displaying a link to this item, for example, the Open Graph image that you see when sharing links within social media. |
## Other use cases
In conclusion, this is just one example of how you can model a blog pattern for your web app. Feel free to reuse this structure and amend it to your needs.
You could also consider including the following use cases in your schema.
- Add the author's social media info. You could set up social media info as a component and embed it in the *Author* model.
- Create a more generic *Person* model with a field for role information. If you need to show some employee information in your front-end, it's a good idea to allow their roles to be stored for this purpose.
## Want to learn more?
Check out the following guides:
- [More example patterns](/content-modeling/examples)
- [How to create a model in Prepr](/content-modeling/managing-models)
- [How to create a component in Prepr](/content-modeling/managing-components)
Source: https://docs.prepr.io/content-modeling/examples/blog
---
# Page
*A page is one of the basic parts of a web app.
Check out our [demo home page](https://acme-lease-v2.vercel.app/en-US) in action.*
## Introduction
This guide takes you through the content modeling process for a page pattern and explains the reasoning behind the modeling decisions. We'll look at how to model a feature-rich web page with a variety of elements. Here is a sample web page we used as a basis for the modeling:

Let's take a closer look at the modeling steps. Using this page as a basis, we see that a number of elements make up the page content. These include:
- **A hero section**
The hero section is the prominent part of the page usually at the top. It has a heading, a sub-heading, an image, and one or more buttons.
- **A feature section**
The feature section showcases important features to highlight and consists of a heading, a sub-heading, button, image and the image position.
- **CTA**
A call-to-action to encourage interaction from the web visitor.
- **Static**
Some static sections to showcase more static info like testimonials.
- **Cards**
Cards are used for things like a selection of blog posts or recommended products. It has a heading, sub-heading, a stack of cards for the items like posts or products.
- **FAQ section**
A FAQ section to show some common questions and the corresponding answers.
- **Contact section**
This section gives visitors the opportunity to contact the company.
Let's look at how to structure a page like this in more detail.
## Page model
In our schema, we've decided to create a generic *Page* model that can be used for different kinds of web pages, for example, a home page, marketing pages, landing pages, etc.
See an example *Page* model below:

Within the *Page* model we define the following fields:
|Field name |Field type| Description|
|------------------|-------------|--------|
|**Title**| [Text](/content-modeling/field-types#text-field) |The title of the page. Required. This title is used internally to identify the page in Prepr.|
|**Slug**| [Slug](/content-modeling/field-types#slug-field) |Part of the URL that is used to link to this page. The slug can also be used for API queries to request this page and is automatically set to the title of the page in our example.|
|**Content**| [Stack](/content-modeling/field-types#stack-field)| The main content of the page. Using the Stack field allows editors to add the elements that make up the web page easily, for example, the hero section, a CTA, FAQ section, etc. |
|**SEO**| [Component](/content-modeling/field-types#component-field)| SEO is an embedded component which contains fields that are used by search engines and social media. We reuse the same SEO component defined in the [Blog pattern](/content-modeling/examples/blog) doc.|
See a complete list of all other available [Prepr field types](/content-modeling/field-types).
## How to model the elements on a page
In our example model above we put the main page content in a *Stack* field.
The *Stack* field allows content editors to easily create all the elements they need on a page.
They can add both components and content items to the stack.
The *Stack* field contains the following components and models in our *Page* model:
|Model/component |Type| Description|
|------------------|-------------|--------|
|**Hero**| Component|The hero component at the top of the page. |\
|**Feature**| Component| The feature component to allow editors to capture a heading, a sub-heading, button, image and the image position (left or right).|
|**CTA**| Component| The component for a call-to-action.|
|**Cards** | Component|The component to show recommendations or posts as cards. The editor can link existing *Product* or *Post* content items. Check out the [*Blog pattern*](/content-modeling/examples/blog#article-model) doc for more details.|
|**FAQ** | Model|A reference to existing reusable question and answer content. |
|**Contact**| Component| A component to allow editors to include a contact form in the page.|
Let's look at each element in detail.
### Hero
The *Hero* component is used to include the most prominent part of the page usually at the top.

The *Hero* component has the following typical fields:
|Field name |Field type| Description|
|------------------|-------------|--------|
|**Heading**| [Text](/content-modeling/field-types#text-field) |The heading usually at the top of the Hero section.|
|**Sub Heading**| [Text](/content-modeling/field-types#text-field) |More descriptive text just below the heading.|
|**Image**|[Assets](/content-modeling/field-types#assets-field)|An asset field that allows editors to include an image in the *Hero* section.|
|**Buttons**| [Stack](/content-modeling/field-types#stack-field) |One or more buttons with their respective fields.|
### Feature
The *Feature* component in a page can be used to highlight important features.

The *Feature* component typically has the following fields:
|Field name |Field type| Description|
|------------------|-------------|--------|
|**Heading**| [Text](/content-modeling/field-types#text-field) |The title of the *Image and text* block.|
|**Sub heading**| [Text](/content-modeling/field-types#text-field) |The text content.|
|**Button**|[Component](/content-modeling/field-types#component-field)|This component allows editors to label the button and to either link the button to a URL, another page in the website, or to another content item. Maximum of one button or link.|
|**Image**|[Assets](/content-modeling/field-types#assets-field)|An asset field that allows the editor to attach an image. Maximum of one asset with `image` asset type.|
|**Image position**| [List](/content-modeling/field-types#list-field)| The position of the image in relation to the text, for example, image to the left of the text or to the right of the text.|
### CTA
The *CTA* component can be used to encourage interaction from the web visitor.

The *Call to action* component typically has at least the following fields:
|Field name |Field type| Description|
|------------------|-------------|--------|
|**Heading**| [Text](/content-modeling/field-types#text-field) |The heading text for this call to action.|
|**Sub Heading**| [Text](/content-modeling/field-types#text-field) |More descriptive text for this call to action.|
### Static
The *Static* component can be used to showcase more static info such as testimonials.

The *Static* component can be made up of at least the following fields:
|Field name |Field type| Description|
|------------------|-------------|--------|
|**Title**| [Text](/content-modeling/field-types#text-field) |The title for this section.|
|**Static Type**| [List](/content-modeling/field-types#text-field) |Based on this value, the front end can determine how to display the static content, for example, testimonials or steps.|
### Cards
The *Cards* component can be used to show highlighted blog posts or recommended products.

The *Cards* component is typically made up of the following fields:
|Field name |Field type| Description|
|------------------|-------------|--------|
|**Heading**| [Text](/content-modeling/field-types#text-field) |The heading text for the collection of cards.|
|**Sub heading**| [Text](/content-modeling/field-types#text-field) |More description text just below the heading.|
|**Cards**| [Stack](/content-modeling/field-types#stack-field) |Used to include several posts or product content items.|
|**Button**| [Component](/content-modeling/field-types#component-field) |This component allows editors to label the button and to either link the button to a URL, another page in the website, or to another content item. Maximum of one button or link.|
### FAQ
The *FAQ* model is useful to include some common questions and the corresponding answers.
By creating a model instead of a component, the content is reusable and the same questions and answers can be referenced in multiple pages.

The *FAQ* model is made up of the following fields:
|Field name |Field type| Description|
|------------------|-------------|--------|
|**Internal Title**| [Text](/content-modeling/field-types#text-field) |The front end uses this field to link to the correct FAQ content item.|
|**Title**| [Text](/content-modeling/field-types#text-field) |The title for the section in the page.|
|**Questions**| [Stack](/content-modeling/field-types#text-field) |A list of questions and their corresponding answers.|
### Contact
The *Contact* component can be used to give website visitors the opportunity to contact the company.

The *Contact* component is typically made up of the following fields:
|Field name |Field type| Description|
|------------------|-------------|--------|
|**Heading**| [Text](/content-modeling/field-types#text-field) |The heading text for this contact form.|
|**Sub heading**| [Text](/content-modeling/field-types#text-field) |More descriptive text just below the heading.|
|**Form title**| [Text](/content-modeling/field-types#text-field) |The contact form title.|
|**Phone number**| [Text](/content-modeling/field-types#text-field) |Used for your company telephone number.|
|**Email**| [Text](/content-modeling/field-types#text-field) |Used to show the company email address.|
|**hubspot\_form\_id**| [Text](/content-modeling/field-types#text-field) |If you [add the HubSpot integration](/integrations/hubspot), you can use a matching `hubspot_form_id` to link to an existing HubSpot contact form.|
|**hubspot\_portal\_id**| [Text](/content-modeling/field-types#text-field) |If you [add the HubSpot integration](/integrations/hubspot), you can use a matching `hubspot_portal_id` to link to an existing HubSpot contact form.|
## What's next?
Now that you know how to model a page, let's go a step further and look at [how to set up personalization](/personalization/setting-up-personalization) doc.
## Other use cases
This guide explains how you can design just one example of a page for your web app. This page can be used for several types of pages, for example: home page or landing pages.
Feel free to use this structure and amend it to your needs.
Another use case we haven't covered could be a **Job postings** page.
In some cases, you may have to access content that is maintained in another system, for example, job postings information.
It makes sense that you may want to retrieve the items from the other system to ensure you have up to date information in Prepr.
In this example, you can include a job postings element on your page that references the job postings from the external system.
Prepr allows you to set up remote content in your model or component which is retrieved from a custom source.
Check out [how to set up a custom remote source](/content-modeling/creating-a-custom-remote-source) doc for more details.
## Want to learn more?
Check out the following guides:
- [More examples](/content-modeling/examples)
- [How to create a model in Prepr](/content-modeling/managing-models)
- [How to create a component in Prepr](/content-modeling/managing-components)
Source: https://docs.prepr.io/content-modeling/examples/page
---
# Navigation
*Navigation is a key structure that is implemented in every web app. In this article, we look at a typical navigation structure and explain the reasoning behind the modeling decisions.*
## Introduction
First, let's look at an example of a top navigation. This structure is the basis for our modeling process:

Using this example as a basis, we see that this navigation has a number of top-level (parent) menu items and these parent menu items have a number of child menu items. Prepr supports this type of nested items with the standard *content reference* field. It's possible for you to create content that references other content, even of the same *Model*. Check out the [Content reference field](/content-modeling/field-types#content-reference-field) docs for more details.
When a user clicks the lowest level child menu item, they are directed to a different page.
Let's look at the *Navigation* model in more detail.
## The navigation model
The *Navigation* model is a simple model, but is our starting point for this pattern.
See an example *Navigation* model below:

Within the *Navigation* model we define the following fields:
|Field name |Field type| Description|
|------------------|-------------|--------|
|**Title**|[Text](/content-modeling/field-types#text-field)|The title of the navigation, for example, *Top navigation*. Required. This title can be used to query the navigation through the API. |
|**Menu items**| [Content reference](/content-modeling/field-types#content-reference-field)|The navigation almost always has several menu items. This field makes a reference to the *Menu item* model. |
See a complete list of all other available [Prepr field types](/content-modeling/field-types).
Now, let's look at the *Menu items* field in more detail.
### Menu items
We set up a *Menu items* field in the *Navigation* model. This field references a *Menu item* model to avoid duplication of menu item content. The idea is that there could be content for the same menu items in different locations throughout the web app. For example, imagine that the same menu item appears in the top navigation as well as in the footer of a web page. This generic *Menu item* model caters for this situation and makes your schema more flexible and robust.

Within the *Menu item* model we define the following fields:
|Field name |Field type| Description|
|------------------|-------------|--------|
|**Title**|[Text](/content-modeling/field-types#text-field)|The title of the menu item visible on the navigation, for example, *Events*. Required. This title can also be used to query the menu item through the API. |
|**Link to page**| [Content reference](/content-modeling/field-types#content-reference-field) |When a user clicks a menu item, this field is used to open the correct internal page linked to this menu item. For more details on the Page model, check out the [Page pattern](/content-modeling/examples/page).|
|**Link to external page**| [Text](/content-modeling/field-types#text-field) |When a user clicks a menu item, this field is used to open an external page linked to this menu item. In Prepr, you can set this text field as HTML and enable the *Link* option.|
|**Description**|[Text](/content-modeling/field-types#text-field)| A short description for the menu item that is visible on the navigation, for example, *Check out our upcoming events*. |
|**Icon**|[Assets](/content-modeling/field-types#assets-field)|An optional icon that represents the menu item.|
|**Children**| [Content reference](/content-modeling/field-types#content-reference-field)|A reference to the *Menu item* model itself to create a parent-child hierarchy. The front-end queries this field to find all the children menu items for a particular parent.|
## Other use cases
In conclusion, this is just one example of how you can model any navigation for your web app. Feel free to use this structure and amend it to your needs.
- If you'd like to specify the display order of your children menu items in the content, consider adding a number field to the menu item model to specify the order. In this way, the front-end doesn't have to be updated when menu items need to be re-ordered.
## Want to learn more?
Check out the following guides:
- [More example patterns](/content-modeling/examples)
- [How to create a model in Prepr](/content-modeling/managing-models)
Source: https://docs.prepr.io/content-modeling/examples/navigation
---
# App config
*Application configuration is static information about a web app that seldom changes. In this article we look at an example of a typical application configuration model.*
{/*
You can create this pattern in Prepr automatically when you create a model. Choose the *App config pattern* template and the model described below will be created for you. */}
## Introducing the single-item-model
A lot of application configuration is not actually visible on a web app, but is essential to creating a working web app. Prepr supports this type of static once-off setup with the *single-item model*. The *single-item model* makes it much simpler for developers to query this type of content. Check out the [Single-item model](/content-modeling/managing-models#single-item-model) docs for more details.
Examples of app config content include, but is not limited to:
- *App name* - This is the name of the web app that is visible, for example when the app appears in a search list.
- *App description* - This is the brief description that is visible, for example when the app appears in a search list.
- *Company contact info* - This is information like the company's address and telephone number that is displayed on a web site.
- *Meta tags* - These are searchable tags at a web app level rather than at a page level.
- *Copyright information* - This is the static text that one often sees at the bottom of a web app to indicate copyright information.
Let's look at an *App config* model.
## An App config model
We define *App config* as a single-item model. This means that a content editor can only create one App config item. A single item also makes it easier for the front-end to query this content.
See an example *App config* model below:

Within the *App config* model we define the following fields:
|Field name |Field type | Description|
|------------------|-------------|--------|
|**App name**|[Text](/content-modeling/field-types#text-field)|The app name is listed in internet searches or in the case of a mobile app is the name search in an app store. |
|**App description**| [Text](/content-modeling/field-types#text-field) | A brief description which is shown together with the *App name* in internet searches.|
|**Company contact info**| [Text](/content-modeling/field-types#text-field) | The company's address and telephone number. This content can then be displayed in the web app.|
|**Meta tags**| [Tags](/content-modeling/field-types#tags-field) | General tags for search engines to find the web app. These tags are not specific to particular pages.|
|**Copyright info**| [Text](/content-modeling/field-types#text-field) | The static text for copyright information on the web app.|
See a complete list of all other available [Prepr field types](/content-modeling/field-types).
## Other use cases
In conclusion, this is just one example of how you can structure app config. Feel free to use this structure and amend it to your needs.
- If you would like to include a *Follow us* box in your web app, you could also design a *Social media links* field that contains links to the company's social media profiles.
- It's possible that your website uses a default CSS other than special styling for specific pages. In this case, you can also include a *Default CSS* field in your App config model.
## Want to learn more?
Check out the following guides:
- [More example patterns](/content-modeling/examples)
- [How to create a model in Prepr](/content-modeling/managing-models).
Source: https://docs.prepr.io/content-modeling/examples/app-config
---
# Next.js Quick start guide
*Estimated duration: 10 minutes*
*This guide shows you how to connect Prepr to a Next.js project to get data from Prepr CMS. You'll learn how to make a simple blog with Next.js and Prepr CMS. By the end of this guide, you'll have a working app that looks like the image below.*

## Prerequisites
You need to have the following setup before you connect your Next.js project to Prepr.
- [A free Prepr account](https://signup.prepr.io)
- [An environment with demo data in Prepr](/project-setup/setting-up-environments#create-an-environment)
- [The latest version of Node.js](https://nodejs.org/en)
## Create a simple Blog website with Next.js and Prepr CMS
## All done
Congratulations! You have successfully connected a Next project to Prepr for a simple Blog app.
## Next steps
To learn more on how to expand your project, check out the following resources:
- [Add A/B testing and Prepr personalization to your Next app](/connecting-a-front-end-framework/nextjs/next-complete-guide)
- [Draft more queries for components and other field types](/graphql-api)
- [How to install and use the Next Tailwind module](https://nextjs.org/docs/app/building-your-application/styling/tailwind-css)
- [Deploy your Next app with Vercel](https://nextjs.org/learn-pages-router/basics/deploying-nextjs-app)
Source: https://docs.prepr.io/connecting-a-front-end-framework/nextjs/next-quick-start-guide
---
# Complete guide to Next.js and Prepr
*This guide shows you how to connect Prepr to a Next.js project including styling, adaptive content, A/B testing and a preview bar.*
Follow the steps below in the recommended order to set up your own working Next.js website with adaptive content, A/B testing and a preview bar.
You can also customize this project to fit the requirements for your web app.
Source: https://docs.prepr.io/connecting-a-front-end-framework/nextjs/next-complete-guide
---
# Caching strategies for Next.js and Apollo Client
*This article gives you insight into caching strategies and our recommendation when connecting your Next.js web app with Prepr CMS using Apollo Client.*
## Introduction
Caching is the process of storing copies of data in a temporary storage layer so that future requests for that data can be served faster.
Instead of fetching data from the CMS every time, cached data can be retrieved quickly from a nearby location like memory, a server, or a CDN.
## Caching layers
When connecting your Next.js front end to Prepr CMS using Apollo Client, caching happens at several layers.
### Next.js
There are different caching mechanisms in Next.js, each serving their own purpose:
- *Request Memorization* is only persistent per request cycle and isn’t relevant for Prepr caching strategies.
- *Data Cache* is turned off by default and can be opted in using `{ cache: 'force-cache' }` with the native `fetch` API.
- *Full Route Cache* is enabled by default, but if a route has a `fetch` request that is not cached then this will opt you out of the *Full Route Cache*. Since caching of the data cache is turned off by default, you will also not use the full route cache.
- *Router Cache* is responsible for caching layouts, loading states and pages on backwards and forward navigation.
In your front end you can configure the caching behavior for individual routes and data requests.
If you don't set any caching options when fetching from the API, both the *Data Cache* and the *Full Route Cache* are not active and data is refetched on every request.
For more details, check out the [Next.js caching docs](https://nextjs.org/docs/app/deep-dive/caching).
### Apollo Client
Apollo Client stores the results of your GraphQL queries in a local, normalized, in-memory cache.
This enables Apollo Client to respond almost immediately to queries for already-cached data, without even sending a network request.
For more details, check out the [Apollo Client caching docs](https://www.apollographql.com/docs/react/caching/overview).
### Prepr CDN
All Prepr content is served by a globally distributed content delivery network (CDN).
When you send your first API request to fetch data from Prepr, the response is cached in an edge cache location.
For more details, checkout the [GraphQL API caching doc](/graphql-api/caching).
## Recommendation
To make the most out of the dynamic Prepr features, personalization and A/B testing, we recommend setting up your front end for [SSR (server-side rendering)](/development/best-practices/csr-ssr-ssg#server-side-rendering-ssr).
Check out the [Next.js complete guide](/connecting-a-front-end-framework/nextjs/next-complete-guide/step-2-make-the-project-dynamic) for an example Next.js project using Apollo Client.
## Prepr Next.js SSG example
If you choose not to use Prepr personalization or A/B testing, you can implement a caching strategy in Next.js and Apollo Client to build an SSG (statically generated) website.
Check out the [Prepr Next.js static Github repo](https://github.com/preprio/prepr-nextjs-static) for example `page.tsx` code to view the Next.js and Apollo Client cache setup.
This project also includes two webhooks, `api/post-published` and `api/post-updated` which reset the cache if triggered.
To create a simple SSG blog site, follow the steps below.
1. Clone the [Prepr Next.js static Github repo](https://github.com/preprio/prepr-nextjs-static).
2. Copy the `.env.example` file to a new `.env` file by running the following command:
```bash
cp .env.example .env
```
3. In the .env file, replace `{YOUR_GRAPHQL_URL}` with the *API URL* of the Prepr *GraphQL* access token from your Acme Lease demo environment.

4. Deploy the app in your preferred deployment tool. You need the deployed URL to set up the webhooks in Prepr in the next step.
5. Configure two webhooks in Prepr to listen for changed and published content and trigger your site to reset the cache.

- Set the **URL** value to `{YOUR_DEPLOYMENT_URL}/api/post-updated`, choose `content-item.changed` for **Events** and choose `Post` for **Models**.

- Set the **URL** value to `{YOUR_DEPLOYMENT_URL}/api/post-published`, choose `content-item.published` for **Events**, and choose `Post` for **Models**.
All done! Now you have a simple SSG blog post site that renders updated content whenever content is changed or published.
## Next steps
To learn more on how to expand your Next.js project, check out the following resources:
- [More data collection details](/data-collection)
- [More about A/B testing](/ab-testing)
- [More about personalization](/personalization)
Source: https://docs.prepr.io/connecting-a-front-end-framework/nextjs/caching-strategies
---
# Nuxt Quick start guide
*Estimated duration: 10 minutes*
*This guide shows you how to connect Prepr to a Nuxt 3 project to get data from Prepr CMS. You'll learn how to make a simple blog with Nuxt and Prepr CMS. By the end of this guide, you'll have a working app that looks like the image below.*

## Prerequisites
You need to have the following setup before you connect your Nuxt project to Prepr.
- [A free Prepr account](https://signup.prepr.io)
- [An environment with demo data in Prepr](/project-setup/setting-up-environments#create-an-environment)
- [The latest version of Node.js](https://nodejs.org/en)
## Create a simple Blog website with Nuxt and Prepr CMS
## All done
Congratulations! You have successfully connected a Nuxt project to Prepr for a simple Blog app.
## Next steps
To learn more on how to expand your project, check out the following resources:
- [Add styling and Prepr personalization to your Nuxt app](/connecting-a-front-end-framework/nuxtjs/nuxt-complete-guide)
- [Draft more queries for components and other field types](/graphql-api)
- [How to install and use the Nuxt Tailwind module](https://nuxt.com/modules/tailwindcss)
- [Deploy your Nuxt app with Vercel](https://vercel.com/docs/frameworks/nuxt)
Source: https://docs.prepr.io/connecting-a-front-end-framework/nuxtjs/nuxt-quick-start-guide
---
# Complete guide to Nuxt and Prepr
*This guide shows you how to connect Prepr to a Nuxt project including styling, adaptive content, and A/B testing.*
Follow the steps below in the recommended order to set up your own working Nuxt website with adaptive content, A/B testing and a preview bar.
You can also customize this project to fit the requirements for your web app.
Source: https://docs.prepr.io/connecting-a-front-end-framework/nuxtjs/nuxt-complete-guide
---
# Laravel Quick start guide
*Estimated duration: 10 minutes*
*This guide shows you how to connect Prepr to a Laravel project to get data from Prepr CMS. You'll learn how to make a simple blog with Laravel and Prepr CMS. By the end of this guide, you'll have a working app that looks like the image below.*

## Prerequisites
You need to have the following setup before you connect your Laravel project to Prepr.
- [A free Prepr account](https://signup.prepr.io)
- [An environment with demo data in Prepr](/project-setup/setting-up-environments#create-an-environment)
## Create a simple Blog website with Next.js and Prepr CMS
## All done
Congratulations! You have successfully connected a Laravel project to Prepr for a simple Blog app.
## Next steps
To learn more on how to expand your project, check out the following resources:
- [Add styling and Prepr personalization to your Laravel app](/connecting-a-front-end-framework/laravel/laravel-complete-guide)
- [Draft more queries for components and other field types](/graphql-api)
- [Check out the Laravel GraphQL SDK repo](https://github.com/preprio/laravel-graphql-sdk)
- [Deploy your Laravel app](https://devcenter.heroku.com/articles/getting-started-with-laravel#deploying-to-heroku)
Source: https://docs.prepr.io/connecting-a-front-end-framework/laravel/laravel-quick-start-guide
---
# Complete guide to Laravel and Prepr
*This guide shows you how to connect Prepr to a Laravel project including styling, adaptive content, and A/B testing.*
Follow the steps below in the recommended order to set up your own working Laravel website with adaptive content, A/B testing and a preview bar.
You can also customize this project to fit the requirements for your web app.
Source: https://docs.prepr.io/connecting-a-front-end-framework/laravel/laravel-complete-guide
---
# React Quick start guide
*Estimated duration: 10 minutes*
*This guide shows you how to connect Prepr to a React project to get data from Prepr CMS. You'll learn how to make a simple blog with React and Prepr CMS. By the end of this guide, you'll have a working app that looks like the image below.*

## Prerequisites
You need to have the following setup before you connect your React project to Prepr.
- [A free Prepr account](https://signup.prepr.io)
- [An environment with demo data in Prepr](/project-setup/setting-up-environments#create-an-environment)
- [The latest version of Node.js](https://nodejs.org/en)
## Step 1: Create a new React project
The instructions below will guide you on how to create an empty React project for your blog app.
### Install React
You can skip this step if you have an existing React project.
1. Open a terminal and execute the command below to create a new React project called `prepr-react`.
```bash copy
npx create-react-app prepr-react
```
2. Now that the project is successfully created, go to the `prepr-react` folder, the root directory of the project, and start the project with the following commands in the terminal:
```bash copy
cd prepr-react
```
```bash copy
npm start
```
3. You should now be able to view your app on your localhost, for example, `http://localhost:3000/`.
4. Open your project with your preferred code editor.
5. Update `App.js` in the `src` folder with the following code to display your blog:
```js filename="./src/App.js" copy
function App() {
return (
Loading...
; if (error) returnError :(
; // Set the query results const articles = data.Articles.items; return (Loading...
; if (error) returnError :(
; const articles = data.Articles.items; return (Loading...
; if (error) returnError :(
; const article = data.Article; return ( <>