# 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. ![quick-start-guide-use-case](https://assets-site.prepr.io/w_1920/4e2edea6-dbeb-4ae8-bd2c-f78ebf6ace7e.jpg) ## 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**. ![add environment](https://assets-site.prepr.io/ki6nbcjodkg//updated-navigation-add-new-environment.png) 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**. ![Start from scratch](https://assets-site.prepr.io/28i2x8s5e9ld//new-environment-start-from-scratch.png) 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. ![quick-start-guide-create-content-model](https://assets-site.prepr.io/w_1920/5c7b4cee-65ee-493b-8df8-58477e39e81f.jpg) Let’s create these models in Prepr: 1. Click the **Schema** tab to open the *Schema Editor*. 2. In the *Models* section, click the **+ Add model** link. 3. Choose **Multi-item model** and 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. ![empty person model](https://assets-site.prepr.io/1eetuzhu9jen//quick-start-guide-empty-person-model.png) 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: ![quick-start-guide-person-model](https://assets-site.prepr.io/5ulschu2ycou//quick-start-guide-person-model-with-fields.png) Now you can add the Article model. 1. Click the **+ Add model** button on the left. 2. Choose the **Multi-item model** option, 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: ![Empty article model](https://assets-site.prepr.io/4stb6440w4d9//quick-start-guide-empty-article-model.png) 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**. ![ Article model with author ](https://assets-site.prepr.io/55ylhz2jqa2m//quick-start-guide-filled-article-model.png) 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. ![Article model completed](https://assets-site.prepr.io/332yhkppxy2u//quick-start-guide-article-with-all-fields.png) ## 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. ![create a person](https://assets-site.prepr.io/vfavn56rrwb//example-person.png) 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. ![create article](https://assets-site.prepr.io/38x1tn6pm1x1//example-article.png) 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. ![GraphQL production access token example](https://assets-site.prepr.io/l24g7i7rwmf//graphql-access-token.png) Make sure you see a green dot and your access token at the end of the url. If you cannot connect, please contact support. ![API explorer example](https://assets-site.prepr.io/350zhceg8aek//api-explorer-example.png) 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) - [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 visitor journey. 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. ## Improved AI text assistant for better results We've improved our AI features for creating content. Now you can, - use AI to improve text in the dynamic content editor - use your own prompts to improve text - continue prompting to fine-tune your initial request ![Ask AI improvements Dynamic content example](https://downloads-site.prepr.io/3kqz5ensr04m-ask-ai-improvements.gif) This update creates a more consistent AI experience so you get better results and speed up your editing workflow. In other words, spend less time editing and more time publishing. Check out the [AI text assistant guide](/ai-text-assistant) for more details. ## Environment-scoped preview URLs in local schemas You can now assign preview URLs to specific environments directly in local schemas. ![Setting preview URLs](https://assets-site.prepr.io/2nb5y9fe6hc1//preview-urls-local-schema-example.png) This makes managing preview URLs across your DTAP workflow much easier. For example, configure all environment-specific preview URLs in Development, sync your schema, and the environment assignments remain intact, no need to reconfigure preview URLs after syncing to Production. Check out the [model settings](/content-modeling/managing-models#preview) for more details. ## New remote source spec to validate your custom endpoint We’ve just released a [new spec for custom remote sources](https://github.com/preprio/remote-source-validation). Now, you can automatically validate your custom endpoint based on its response format. This way you make sure you release a Prepr-compatible custom endpoint with fewer mistakes. For more details, check out the [custom remote source guide](/content-modeling/creating-a-custom-remote-source#validate-the-custom-remote-source). ## Improved subscription page gives you more clarity on usage With the improved subscription page, you can easily view your usage at a glance and enable notifications when your usage hits a threshold. ![Example subscription page](https://assets-site.prepr.io/4qi3w7pbogs3//subscription-page-highlight-notify-me.png) This gives you better visibility and control for total peace of mind. For more details, check out the [subscription guide](/project-setup/managing-your-subscription). ## New tracking code fallback to record view events Previously, the Prepr tracking code only recorded view events by identifying content items with the specific `id` meta tag. Now, it also automatically records view events by matching the URL path (slug) to the correct content item when the meta tag is not present. This update prevents data gaps caused by accidental omission of the `id` meta tags in your front-end code, ensuring your analytics remain complete. Check out the [recording events guide](/data-collection/recording-events#view) for more details. ## Prepr MCP server public beta now live Thanks to our users who've tried out the closed beta release of the Prepr MCP server we've made improvements and can provide [real-life use cases](/prepr-mcp-server/use-cases). Here are some of the enhancements: - Migrated server domain to `https://mcp.prepr.io` - Added OAuth support for secure agent connection - AI agent scopes mirror your authenticated user role permissions For a full list of updates since the closed beta, checkout the [release notes](/prepr-mcp-server/release-notes). To get started and connect your own AI agent, check out the [full MCP docs](/prepr-mcp-server). ## Case-insensitive personalization for UTM values We’ve improved how UTM values are matched in segment conditions. Previously, UTM values required an exact case match. For example, a condition targeting SpringCampaign would not match springCampaign. Now, UTM values are matched case-insensitively, making visitor segmentation and personalization more intuitive. This improvement helps prevent unexpected results caused by inconsistent UTM capitalization across campaigns and marketing tools. ## Password leak detection across authentication flows We've implemented leaked credential detection across all key authentication flows: - Sign-in - Password reset - Password creation after profile invite During these processes credentials are validated against breach intelligence, and users are required to reset their password if a compromised password is detected. ![example leaked password check](https://assets-site.prepr.io/5sxn8pdj784g//leaked-password-check-example.png) This improvement strengthens account security by preventing the use of exposed credentials that are known from external data breaches. By proactively detecting and blocking leaked passwords, we reduce the risk of credential stuffing attacks and unauthorized account access, significantly improving protection for user accounts and overall platform security. Check out [this blog post](https://blog.cloudflare.com/helping-keep-customers-safe-with-leaked-password-notification/) for more details. ## Introducing the Jotform integration With the new integration to this online form and surveys platform, you can embed Jotform forms directly into your content items. ![example content item](https://assets-site.prepr.io/1x01fxgq9zu2//example-jotform-form.png) This means you keep your content and related Jotform forms in one place. Check out the [Jotform integration guide](/integrations/jotform) for more details. ## Introducing the ActiveCampaign integration With the new integration to this email marketing platform, you can embed ActiveCampaign forms directly into your content items. ![example content item](https://assets-site.prepr.io/58zmwkfuphcg//example-content-item-with-activecampaign-form-selector.png) This means you keep your content and related ActiveCampaign forms in one place. Check out the [ActiveCampaign integration guide](/integrations/activecampaign) for more details. ## Improved Algolia integration for more control over indexing We’ve overhauled the Algolia integration to give you total control over how Algolia indexes your content. Instead of relying on hidden internal rules, you can now use GraphQL queries to explicitly define exactly which model fields sync to Algolia and precisely when to generate separate records. ![Algolia integration setup with index query](https://assets-site.prepr.io/1n27zjxkam5w//algolia-search-index-example.png) Now you have full control over the data flow, ensuring search results are more relevant and streamlining your Algolia index size by syncing only what you actually need. Check out the [Algolia setup guide](/integrations/algolia) for more details. ## Webhook events updated with locale info We've updated two webhook events with locale info to give you more accurate automation and clearer visibility into content item changes and deletions. 1. Previously, the `content_item.deleted` event only triggered for an entire content item deletion. Now, this event also fires when a single language variant of a content item is deleted. You can differentiate between a full deletion and a partial (locale-specific) deletion using the following parameters: - `scope`: Values can be either `item` (full deletion) or `locale` (partial deletion). - `locale`: If the `scope` value is `locale`, this value is the locale string, for example: `en-US`. 2. Previously, the `content-item.changed` event did not indicate which language variant of a content item was actually changed. Now, this event fires for every language variant updated. The `locale` parameter value indicates exactly which is updated, for example: `en-US`. Check out the [webhooks guide](/development/best-practices/webhooks) for more details. ## Choosing environments to search shared content items Previously, when you added searchable models to a *Stack* or *Content reference* field in a shared model, you could either choose the model to be available to all environments or a single environment. Now, you can choose specific environments for searchable models. For example, when editors need to search content items common to multiple sites, but shouldn't view or include test content items. ![content reference example](https://assets-site.prepr.io/74tbexkhl4m1//content-reference-example.png) This means a cleaner editor experience because they see exactly what they need. Check out the [Shared schema guide](/project-setup/architecture-scenarios/shared-schema#define-environments-for-allowed-models) for more details. ## Environment-scoped preview for shared model Previously, when you set up preview URLs in a shared model, editors in any environment in the organization could see the full list of preview URLs you added. Now, you can scope preview URLs to individual environments when setting them up. ![environment-scoped preview setup](https://assets-site.prepr.io/30l2j00dl55j//organization-level-preview-setup-example.png) This cleans up the UI for visual editing as editors only see preview options relevant to their environment, saving them time and avoiding unnecessary scrolling and clicking wrong preview options. For more details, check out the [preview setup guide](/project-setup/setting-up-previews-and-visual-editing#set-up-preview-urls). ## AI-generated text for images Based on your feedback on the [Beta release](#ai-generated-alt-text-for-images-beta-release), we’ve officially launched AI-generated text for images. When uploading new images get AI-generated alt text, descriptions, or comma-separated keywords instantly. ![Example image with AI text values](https://downloads-site.prepr.io/4nmdjrif3sqj-generated-ai-text-for-uploaded-image.gif) This means you save time on manual entry and boost SEO rankings without the extra effort. Check out the [AI integration guide](/integrations/image-processing/ai) to activate this feature. ## Uploading files without an official MIME type Previously, when you uploaded a file without an official MIME type, this file could not be processed. For example, files with a `.bgi` extension. We've updated the file upload to allow files without an official MIME type, using the file extension to set a fallback [MIME type](https://mimetype.io/all-types). Also, when a MIME type has multiple extensions, we keep the original extension of the file. This means your files remain in their original format, ready to use in content items and processed. For more details, check out the [uploading assets](/content-management/managing-assets/managing-assets#uploading-assets) doc for more details. ## Introducing the Propeller commerce integration The new *Propeller* integration allows your team to easily include Propeller products in content items. ![propeller products example](https://assets-site.prepr.io/7tb7xmi3kvl//propeller-example-products.png) This means content editors can work more efficiently and error-free by simply choosing the relevant Propeller entries directly in Prepr. For more details, check out the [Propeller integration guide](/integrations/propeller). ## Defining percentage-based field widths With a new option to set field width, we've replaced the field columns fixed structure with a more flexible percentage-based option for model and component fields. ![set field width example](https://assets-site.prepr.io/53blx8g8hj0k//set-field-width.png) This visual improvement means editors can more easily and quickly scan and edit text fields in content items. Check out the [models guide](/content-modeling/managing-models#defining-field-width) for more details. ## Improved schema sync visibility We've updated the schema UI and since syncing is an important schema action, we've moved the sync schema action to the top of the page. ![GitHub schema sync example](https://assets-site.prepr.io/f4zxrsatpu9//github-sync-out-of-sync-example.png) With this update, you also have clarity on which repo, branch and commit the schema was last synced with and whether the schema is in sync with the branch or vice versa. Check out the [schema sync guide](/development/working-with-cicd/syncing-a-schema#check-the-result) for more details. ## New field setting to declutter content item filter menus With the new **Show in filters** setting, developers can declutter the editing experience by hiding *List*, *Stack* and *Content reference* fields from the content item filter menus. ![show in filter setting](https://assets-site.prepr.io/11913k2evzxa//show-in-filter-setting.png) It’s about reducing noise and helping your editors focus on the data that actually matters. For example, when editors search *Product* content items, the product rating (list field) doesn't add value to the search because it would return too many results. Check out the field settings of the [stack field](/content-modeling/field-types#stack-field), [list field](/content-modeling/field-types#list-field) or [content reference field](/content-modeling/field-types#content-reference-field) for more details. ## Searching through your schema instantly Find your models, components, enumerations, and remote sources instantly with the new schema search bar. ![schema search](https://downloads-site.prepr.io/6hr5azh31shz-search-schema-no-feedback.gif) This way you stay focused on building your schema rather than searching. Check out the [models guide](/content-modeling/managing-models#search-models) for more details. ## Improved commenting on content items You can now add content item comments to specific fields and for a specific locale of the content item, making it possible to provide more granular and actionable feedback. ![Add comment example](https://assets-site.prepr.io/6qq13kb1u068//add-comment-example.png) This means you can follow your editing review process directly in Prepr speeding up your team collaboration and publication of content items. Check out the [collaboration guide](/content-management/collaboration#commenting) for more details. ## Manage content with AI agents using the new Prepr MCP server With the Prepr MCP server, you can create AI agents to manage content in your Prepr CMS environment with natural language prompts. For example, editors who usually write article posts in a tool like Notion can ask the AI agent to create content items for these posts. ![example AI agent chat](https://assets-site.prepr.io/5a36ghd8yn3j//chat-example.png) This means you can automate the grunt work so your team can focus on more strategic tasks. Check out the [Prepr MCP server overview](/prepr-mcp-server) to learn how to set it up for AI agents. ## Managing custom event types You can now set the **Display name** and the **Visibility** of custom event types directly in Prepr. For example, to change a technical event type name `Scrolled50` to something like *Scrolled 50% of the page* or to hide old events with an outdated event type. ![Event type list](https://assets-site.prepr.io/2lx4vy8vn3ed//custom-event-type-settings.png) This means that you and your marketers get a clear clutter-free view of events and only see relevant metrics. Check out the [Event type settings](/data-collection/recording-events#managing-custom-event-types) for more details. ## Expanded trigger criteria for *content\_item.invalidated* webhook event We’ve updated the criteria for the `content_item.invalidated` webhook event to provide better synchronization between your external systems and published content. Previously, this event was triggered for external system changes to a remote source item. Now, it also triggers for [API `PATCH`](/mutation-api/content-items-create-update-and-destroy#patch-a-content-item) updates. This means if you update a published content item via the API `PATCH` request, the `content_item.invalidated` event will fire automatically. Check out the [webhooks guide](/development/best-practices/webhooks#content-item-events) for more details. ## Fixed validation for required fields after hidden conditional sections We fixed an issue where required fields following a conditional section were incorrectly ignored when that section was not shown. Previously, this could allow content to be published without completing required fields. With this fix, required fields after a hidden conditional section are now validated correctly before publication. ## Schema validation based on new Prepr schema spec We've just released a [Prepr schema validation](https://github.com/preprio/action-schema-validation) using the new [Prepr schema spec](https://github.com/preprio/action-schema-validation/blob/main/spec/2026-03-05.json5). Now, you can automatically validate your schema JSON files in *GitHub* to ensure you import a valid Prepr schema every time. This release lays the foundation for the next steps to use AI to generate a fully validated Prepr schema. For more details, check out the [schema validation guide](/development/working-with-cicd/validating-a-schema). ## Prepr Next.js package version 2.2.5 is available We've just released a new version of the Prepr Next.js package. Version 2.2.5 includes a manual override of the `fast-xml-parser` to solve the `CVE-2026-25128` DoS vulnerability. We strongly recommend you upgrade your installation of the Prepr Next.js package, where applicable. For more details, check out the [Prepr Next.js package guide](/prepr-nextjs-package). ## Remote source settings preserved in schema sync We’ve updated the behavior of the *Direct schema sync* and the schema import (via *GitHub*, *GitLab*, *Bitbucket* or *Azure DevOps*) for existing remote sources. Previously, an existing remote source was always fully synced. From now on, the URL, headers, and image domains of an existing remote source will no longer be updated during a schema sync and will be ignored instead. This matches the current behavior of *Preview URLs* and helps prevent manual rework after each sync, especially when test or development URLs need to remain unchanged. Check out the [Schema sync guide](/development/working-with-cicd/syncing-a-schema) for more details. ## New Prepr Next.js package version 2.2.x is available The newest version of the Prepr Next.js package now automatically detects and handles stega encoding. Stega encoding uses hidden characters so editors can click and edit content directly from the preview. This update means you no longer need to write extra code to clean up these hidden characters which could cause misalignment of some UI elements in the live preview. Check out the [Prepr Next.js package guide](/prepr-nextjs-package) for more details. ## Legacy API deprecation on August 1st, 2026 As part of our effort to streamline our API infrastructure, the legacy Prepr API endpoint `api.eu1.prepr.io` will expire and be removed on August 1st, 2026. If your application currently uses `api.eu1.prepr.io`, update your implementation before then. For write operations (mutations), update your endpoint to `mutation.prepr.io`. For read-only operations (queries), we strongly recommend updating your endpoint to `cdn.prepr.io`. Contact [Prepr support](mailto:support@prepr.io?subject=Request%20AI%20activation%20for%20image%20text%20values) if you have any specific questions. ## AI-generated alt text for images (Beta release) When uploading new images you can now get AI-generated text values instantly. For example: alt text, specific descriptions, or comma-separated keywords. This means you save time on manual entry and boost SEO rankings without the extra effort. ![Example image with AI text values](https://downloads-site.prepr.io/4nmdjrif3sqj-generated-ai-text-for-uploaded-image.gif) Contact [Prepr support](mailto:support@prepr.io?subject=Request%20AI%20activation%20for%20image%20text%20values) to activate AI-generated text for images in your environment. ## Improved linked content visibility With the improved linked content visibility, you can now get a high-level view of linked content items from the content item list. ![view linked content items gif](https://downloads-site.prepr.io/70kmn43zrvy1-view-linked-content-items.gif) This removes the need to open individual items to investigate dependencies and therefore speeds up your review of linked content items. For more details, check out the [content management doc](/content-management/managing-content/managing-content-items#view-linked-content-items). ## SSO-ready invites speed up sign-ins Inviting new users to Prepr is now smoother when you use SSO, for example, *Microsoft Entra ID* or *SAML 2.0*. As an administrator, you can now assign roles upfront by simply inviting the new SSO user. This means users no longer need to wait for an admin to grant access after their first SSO sign-in. When the user clicks the **Activate** link in the invite email, Prepr automatically routes them to the correct SSO sign-in flow (instead of email + password), so they can start working right away. Check out the [managing users guide](/project-setup/managing-users#send-invitation-to-sign-in) for more details. ## New webhook event for remote source item changes We’ve added a new event to our webhooks: `content_item.invalidated`. This new event triggers whenever remote source data linked to a content item changes. This means you can now set up a webhook to notify your front end the moment the remote source data becomes stale. For more details, check out the [webhooks guide](/development/best-practices/webhooks#content-item-events). ## Additional granular permissions to manage content items In addition to the [action-based content permissions](/stay-updated/changelog2025#introducing-granular-permissions-to-manage-content-items) we released recently, you can now extend user role permissions and content item access with the following additional features: - *Direct content item sharing* - You can now grant specific users access to individual content items. This allows you to easily work with freelancers or agencies while maintaining strict data privacy. ![share item option](https://assets-site.prepr.io/98ujghrpwr//share-one-content-item.png) - *On-demand access requests* - When users try to open a linked content item they don't have access to, they can directly request access within Prepr with this new workflow. ![Request access to linked author content item](https://assets-site.prepr.io/36uc3o43vtuo//request-access-workflow.png) - *Show my items only* - You have a new setting to allow a user to only access content items they've created or items explicitly shared with them. For example, a freelance editor who only needs to access content items they're assigned to work on. ![User role - Items related to user option](https://assets-site.prepr.io/1xjumxhyxr6e//organization-user-role-items-related-to-user-only-option.png) - *Scoped content access* - Allows users to access only content items in specific workflow stages. For example: A translator who only needs to access content items in the *Review* or *Translation* workflow stages. ![Content restrictions - German translator example](https://assets-site.prepr.io/ddhyi2zmysr//content-restrictions-german-translator.png) These new access right features enhance data security, prevent accidental errors and increase user focus for certain roles, like freelance editors. Check out the [user role guide](/project-setup/managing-roles-and-permissions#content-management-permissions) for more details. ## Introducing the ProspectPro integration With the new ProspectPro integration, you can easily connect Prepr to this B2B prospecting platform. This integration lets you segment website visitors based on their company industry and company size. ![ProspectPro segment example](https://assets-site.prepr.io/30x5go0v7mi4//customer-segment-example.png) By segmenting visitors this way you can personalize content for an enhanced user experience for your B2B audience. Check out the [ProspectPro integration guide](/integrations/prospectpro) for more details. ## Activate integration with Prepr directly in HubSpot Marketplace We've introduced a streamlined authorization flow that allows you to activate the integration with Prepr directly from the HubSpot Marketplace. This makes the process seamless and fully contained within the HubSpot environment. ![Prepr app in HubSpot Marketplace](https://assets-site.prepr.io/14ojkq3xkuni//prepr-app-in-hubspot-marketplace.png) Check out the [HubSpot integration guide](/integrations/hubspot) for more details. 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. ## Q1 & Q2 2026 ### Enhanced *Ask AI* with custom and inline prompts We are introducing an *AI Optimize* option in *Dynamic Content* Fields, allowing users to refine or improve content automatically. By expanding the existing *Ask AI* functionality with custom prompts and inline prompting, we're 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. ### Improve experiment list and experiment setup guidance We’ll improve the experiment overview and setup flow to make experiments easier to create, understand, and learn from. This includes clearer guidance during setup, better visibility into required tracking and metrics, and a more informative experiment list so teams can quickly see status, configuration quality, and next steps. ### Remote source specs files By providing clear spec files with improved guidance, we'll make it easier for you to build your own remote source for external data imports. With this update, we are simplifying setup, reducing integration guesswork, and helping you to validate remote source behavior more quickly and consistently. ### Environment management Improve working with multi-site set up (shared schema). Export and import environment settings (via Git). Set environments per preview URL (to determine which URL is visible in which environment). Also select environments in reference/stack field, to select the environments from which content can be chosen. ### Multiselect enumeration Currently it is only possible to choose 1 value from a list (enumeration). As per your request, we'll add the option to use a multi-select list. ### Improved content checks for GEO/AEO Use AI to help create stronger content in Prepr, with built-in guidance on how to make content index-ready. This roadmap item focuses on assisting editors with content quality, structure, and completeness, so content is easier to optimize for search, discovery, and downstream AI or indexing use cases. ### 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. ### 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. ### 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. 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 visitor journey. 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 visitor 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 visitor 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. ![Recommendations-popular-items](https://assets-site.prepr.io/w_1920/a54d44b2-34a0-4396-8fe8-5d2d7644018b.jpg) 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. ![Get content item ID](https://assets-site.prepr.io/514uv9yt2crq//copy-content-item-id.png) ### 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. ![GraphQL production access token example](https://assets-site.prepr.io/l24g7i7rwmf//graphql-access-token.png) 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 The recommendation algorithm for similar items finds items based on the following criteria: |Criteria|Default weight|Description| |--------|----|------| |Topics |1.4| Highest weight. Topics are extracted automatically by the AI text analysis engine. It identifies specific people, places, or concepts within the item text and finds items with matching topics.| |Content References|1.2| Matches content items linked to the main item through any content references whether in the *Stack*, *Component* or *Dynamic content* field. For example, articles in the same category and articles by the same author.| |Tags|0.8| Matches items based on tag values in the main content item.| You can tweak the default logic to align with your own business priorities. For example, if your content items are related more by their common tags rather than linked items, you can increase the importance of *Tags*. 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: 0 tags: 1 references: 0.5 } ) { items { _id title } } } ``` - We added rules: **`{ entities: 0, tags: 1, references: 0.5 }`** to indicate that topics should not be included and that the tag criteria has higher priority than references. 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. ![Get content item ID](https://assets-site.prepr.io/514uv9yt2crq//copy-content-item-id.png) 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. ![GraphQL production access token example](https://assets-site.prepr.io/l24g7i7rwmf//graphql-access-token.png) 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. ![GraphQL production access token example](https://assets-site.prepr.io/l24g7i7rwmf//graphql-access-token.png) 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 --- # AI-friendly documentation *From this guide, you'll learn how to use Prepr's machine-readable documentation formats with AI coding assistants for faster, more accurate development.* ## Introduction Prepr's documentation is available in LLM-friendly formats that make it easy to integrate with AI coding assistants like Claude, ChatGPT, Cursor, and GitHub Copilot. These formats follow the [llms.txt](https://llmstxt.org/) standard, providing machine-readable documentation that AI assistants can use as context when helping you build with Prepr. By adding Prepr documentation to your AI assistant, you'll get: - Accurate answers based on the latest Prepr documentation - Code suggestions that follow Prepr best practices - Faster development with context-aware assistance - Reduced errors from outdated or incorrect information ## Available formats Prepr documentation is available in three LLM-friendly formats: ### llms.txt The `llms.txt` file provides an index of all documentation pages with titles and descriptions. **URL:** **Best for:** Quick reference and helping AI assistants find relevant documentation sections. ### llms-full.txt The `llms-full.txt` file contains the complete Prepr documentation in a single, machine-readable text file. **URL:** **Best for:** Providing full context to AI assistants for comprehensive answers about Prepr. ### Markdown format (.md) Any documentation page can be accessed in markdown format by appending `.md` to the URL. **Example:** **Best for:** Getting the raw markdown content of individual pages for focused context. ## Using with AI ## Tips for using AI assistants with Prepr Source: https://docs.prepr.io/ai-friendly-docs --- # AI agent-ready best practices for front-end applications *This guide gives you some tips on how to build a front-end application that AI crawlers, RAG (Retrieval-Augmented Generation) agents, and LLM search engines can easily fetch, chunk, and parse.* ## Introduction AI-powered search engines, chat assistants, and retrieval agents increasingly fetch web pages directly to answer questions, compare products, and cite sources. If your front end is hard to crawl, slow to render, or difficult to parse, those systems may skip your content entirely or extract it poorly. Being AI agent-ready means serving clean, accessible, machine-readable pages from the first request. Your content should be available without unnecessary session barriers, easy to interpret through semantic HTML and structured data, and fast enough for bots that operate with short timeouts. This guide focuses on the front-end implementation patterns that help AI agents access and understand your site reliably. This work supports Generative Engine Optimization (GEO), which focuses on making your content easier for AI systems to retrieve, interpret, and cite in generated answers. In practice, AI agent readiness is the technical foundation for GEO: if agents cannot fetch and parse your front end reliably, your content is much less likely to surface in AI-powered experiences. ## Infrastructure security (Preventing false positives) Web Application Firewalls (WAFs) and rate-limiters are engineered to mitigate DDoS attacks and malicious scrapers. However, default security rules frequently group legitimate AI agents into generic "Bad Bot" or "Unknown Scraper" categories, blocking them entirely. ### WAF customization Configure your WAF to allow verified AI bots, not just requests that claim a bot-like `User-Agent`. Treat the header as a hint, then verify it against published bot IP ranges, reverse DNS rules, or your provider's bot verification program. Instead of hard-blocking high-frequency automated traffic from these sources, move them to a Managed Challenge (like Cloudflare Turnstile) rather than an interactive text/image CAPTCHA, which headless AI parsers cannot bypass. ### Verify the bot `GPTBot`, `OAI-SearchBot`, `ChatGPT-User`, `ClaudeBot`, `Claude-Web`, `claude-user`, `PerplexityBot`, and `Google-Extended` are useful detection hints, but they are not identity proofs. At a minimum: - Match the request `User-Agent` against an explicit allowlist. - Verify that the request originates from a published vendor IP range or a provider-level verified-bot program. - Keep a separate fallback policy for unknown automation so spoofed browser traffic does not inherit the same bypass. This matters because a middleware bypass that trusts the `User-Agent` string alone can be trivially spoofed. ### Explicit robots.txt configuration Ensure your root directory explicitly grants access to generative engines. Traditional Googlebot handles indexation for standard search, but specific tokens dictate LLM training and RAG ingestion. Configure your robots.txt as follows: ```plaintext filename="robots.txt" copy User-agent: GPTBot Allow: / User-agent: OAI-SearchBot Allow: / User-agent: ClaudeBot Allow: / User-agent: Claude-Web Allow: / User-agent: claude-user Allow: / User-agent: PerplexityBot Allow: / User-agent: Google-Extended Allow: / # Secure internal API routes and admin panels from scrapers Disallow: /api/private/ Disallow: /admin/ ``` ## State-free middleware Modern front-end applications frequently use middleware layer checks to detect cookies, manage geolocation routing, or enforce cookie-consent scripts before rendering page layouts. However, AI agents usually operate with little or no durable browser state. Training crawlers rarely preserve state, and even in-product browse tools that carry user context still frequently fetch pages without your expected session cookies. If your front-end requires a valid session or cookie acknowledgment to return content, the bot will scrape a blank page or get caught in a redirect loop. To fix this, write an exception rule directly into your edge/server middleware (such as the Next.js `middleware.ts`) that detects verified AI user-agents and bypasses client-side session or location checks. Deliver your content in Prepr transparently on the initial anonymous HTTP GET request. For example, in Next.js: ```ts filename="middleware.ts" copy const AI_BOT_UA = /GPTBot|OAI-SearchBot|ChatGPT-User|ClaudeBot|Claude-Web|claude-user|PerplexityBot|Google-Extended/i function isVerifiedAIBot(request: NextRequest) { const userAgent = request.headers.get('user-agent') ?? '' if (!AI_BOT_UA.test(userAgent)) { return false } // Pair the UA allowlist with IP verification, reverse DNS validation, // or your WAF provider's verified-bot signal before bypassing auth logic. return request.headers.get('x-bot-verified') === '1' } if (isVerifiedAIBot(request)) { return NextResponse.next() } // Existing geolocation, consent, or session enforcement goes here. return NextResponse.next() } ``` Keep the allowlist small and explicit, and document that the strings can change over time. For OpenAI specifically, `ChatGPT-User` is user-triggered retrieval traffic rather than an autonomous crawler, so manage it in middleware or WAF policy rather than assuming `robots.txt` alone will control it. ## Optimize the ingestion layer (llms.txt) Traditional search engines and AI agents use `sitemap.xml` for discovery. For AI agents, you can complement the sitemap by giving them a condensed, machine-friendly summary of your most important content in one place. Implement this with an `llms.txt` (and a more comprehensive llms-full.txt) at the root of your front-end repository (https://yourdomain.com/llms.txt). An `llms.txt` file is plain Markdown. A practical structure is: - An H1 with the site or product name - A short blockquote that explains what the site contains - Section headings for major content areas - One link per page with a short description For example: ```md filename="llms.txt" copy # Prepr Documentation > Complete documentation for Prepr CMS - a headless CMS for building personalized digital experiences. ## Pages - [Prepr CMS Documentation - Headless CMS for modern applications](https://docs.prepr.io/index): Learn how to build fast, scalable applications with Prepr CMS. Complete guides for Next.js, Nuxt, Laravel, and more. Get started with our headless CMS today. - [Quick Start Guide - Get Started with Prepr CMS in 15 Minutes](https://docs.prepr.io/quick-start-guide): Learn how to set up Prepr CMS, create content models, add content, and retrieve it using the GraphQL API. Perfect for developers new to headless CMS. - [Changelog - Latest Updates and Features | Prepr CMS](https://docs.prepr.io/changelog): Stay up to date with the latest Prepr CMS features, improvements, and bug fixes. See what's new in our headless CMS platform. - [Prepr CMS product roadmap - Upcoming features and improvements](https://docs.prepr.io/roadmap): Explore Prepr's product roadmap to see upcoming features, integrations, and improvements. Learn what we're building for the future of headless CMS. - [Setting up your production-ready Prepr project](https://docs.prepr.io/project-setup): Learn how to set up your Prepr project for production with our comprehensive guide and essential resources. - [Content modeling in Prepr CMS](https://docs.prepr.io/content-modeling): Learn how to set up schemas and models effectively in Prepr CMS for organized content management. - [Connecting a front-end framework with Prepr CMS](https://docs.prepr.io/connecting-a-front-end-framework): Learn how to connect your favorite front-end frameworks to Prepr CMS for personalized content delivery. - [Developing with Prepr CMS: guides and best practices](https://docs.prepr.io/development): Learn how to develop with Prepr CMS, including front-end frameworks, CI/CD, and integrations for a smooth development experience. - [Guide to content management in Prepr](https://docs.prepr.io/content-management): Learn how to manage content, assets, localization, and collaboration in Prepr CMS effectively. - [Data collection guides for Prepr CMS](https://docs.prepr.io/data-collection): Learn about data collection features in Prepr and how to set up tracking, recording, and managing visitor data effectively. ... ``` For Prepr projects, this file does not need to be static. You can generate it dynamically from Prepr content: - Generate `llms.txt` from Prepr content in a route handler by querying published pages through the GraphQL API. - Fetch a curated list of published docs pages from the Prepr GraphQL API in a route handler or edge function. - Use editorial metadata such as title, summary, category, and slug to build the Markdown structure. - Regenerate the output when content changes if needed, for example, by using Prepr webhooks to revalidate static pages. ## Zero-latency renders and Edge caching AI scrapers are heavily optimized for processing speed; they will not wait for slow backend database operations or sluggish API responses. Most AI crawlers enforce strict internal connection timeout limits (frequently between 2 to 5 seconds). ### Server-rendered and prerendered pages Never rely on heavy client-side JavaScript fetching that serves a loading spinner for several seconds. The page source must contain the full text content immediately upon the initial server response. ### Time to First Byte (TTFB) mitigation Move your data fetching closer to the bot. Use server-side or CDN caching to avoid repeated origin work for the same content. Cache completely rendered HTML pages at the CDN edge so that when an AI bot hits a content URL, the response time is safely under 200ms. Also keep canonical URLs direct and stable. Avoid redirect chains longer than one 301 hop, and make sure each document resolves to a single canonical URL so retrieval systems do not split citations across duplicate paths. ## Enforce rigid semantic HTML When an LLM scraper successfully fetches your page, it strips out styling and looks strictly at the document hierarchy to define context and determine which answers map to specific headings. In your layout, map your content fields to explicit, native HTML semantic elements. Never use styled `
` or `` tags to replace headings. Ensure `

`, `

`, and `

` tags follow a sequential hierarchy. Isolate definitions, feature callouts, or summary takeaways using structural semantic tags like `