Appearance
Are you an LLM? You can read better optimized documentation at /getting_started/quick_start.md for this page in Markdown format
Quick start
Note: This repository is no longer officially maintained as of Jan, 2023. Feel free to use it, fork it and patch it for your own needs.
This guide provides the fastest path to getting the application up and running on your local machine. By using the pre-configured, read-only example Contentful space, you can explore the application's core features with minimal setup.
Requirements
- .NET Core 2.1 SDK
- Git
- Contentful CLI (only required for write access)
Using the example Contentful space
The application is designed to work out-of-the-box with a demonstration Contentful space. This allows developers to immediately run the project and understand its structure without needing to first create and configure a Contentful account.
The credentials for this read-only space are stored directly in the project's configuration file:
json
// File: TheExampleApp/appsettings.json
{
"ContentfulOptions": {
"DeliveryApiKey": "<DELIVERY_ACCESS_TOKEN>",
"PreviewApiKey": "<PREVIEW_ACCESS_TOKEN>",
"SpaceId": "<SPACE_ID>",
"UsePreviewApi": false
}
}1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
Key Points:
- Read-Only Access: The default credentials only permit fetching published content via the Contentful Delivery API (CDA). You will not be able to edit or create content.
- Session vs. File Credentials: The application can use credentials from
appsettings.jsonor from the user's session. The default is to use the file-based credentials. TheSettings.cshtmlpage logic differentiates between these two states to inform the user of the current configuration source. - Full Experience: To experience the full end-to-end workflow, including editing content and seeing draft previews, you must configure the application to use your own Contentful space. For detailed instructions, refer to the Contentful Setup guide.
Running the application
Clone the repository:
bashgit clone https://github.com/contentful/the-example-app.csharp.git cd the-example-app.csharp1
2Restore dependencies: This command downloads and installs all the required NuGet packages, including ASP.NET Core, the Contentful SDK, and xUnit for testing.
bashdotnet restore1Run the application: This command builds the project and starts the Kestrel web server.
bashdotnet run1
By default, the application will be available at http://localhost:3000.
Exploring the application
Once the application is running, navigate to http://localhost:3000 in your browser. The home page serves as an excellent example of the application's core architectural pattern: dynamic page rendering based on content modules fetched from Contentful.
The page model for the index (Index.cshtml.cs) fetches a single "layout" entry from Contentful where the slug is "home".
csharp
// File: TheExampleApp/Pages/Index.cshtml.cs
public async Task OnGet()
{
// Constructs a query to find the 'layout' content type with a slug of 'home'.
// It includes linked entries up to 4 levels deep to ensure all content modules are fetched.
var queryBuilder = QueryBuilder<Layout>.New
.ContentTypeIs("layout")
.FieldEquals(f => f.Slug, "home")
.Include(4)
.LocaleIs(HttpContext?.Session?.GetString(Startup.LOCALE_KEY) ?? CultureInfo.CurrentCulture.ToString());
var indexPage = (await _client.GetEntries(queryBuilder)).FirstOrDefault();
IndexPage = indexPage;
// ...
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
The corresponding Razor view (Index.cshtml) iterates through the ContentModules collection of the fetched layout. It uses the type name of each module to dynamically render the appropriate partial view. This demonstrates a powerful, content-driven composition pattern.
razor
// File: TheExampleApp/Pages/Index.cshtml
@page
@model IndexModel
@{
ViewData["ActivePage"] = "Home";
ViewData["Title"] = "Home";
}
<div class="layout-centered">
<vc:editorial-features sys="@Model.SystemProperties"></vc:editorial-features>
</div>
<div class="modules-container">
@if (Model.IndexPage.ContentModules == null || Model.IndexPage.ContentModules.Count == 0)
{
@Html.Partial("NoContent")
}
else
{
@foreach (var module in Model.IndexPage.ContentModules)
{
@Html.Partial(module.GetType().Name, module)
}
}
</div>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
Viewing courses
Navigate to the "Courses" section via the main navigation. This page (/courses) lists all available courses and demonstrates category-based filtering.
- URL Structure: The base URL
/coursesshows all courses. Selecting a category updates the URL to/courses/categories/{slug}, filtering the content accordingly. - Component-Based Rendering: The page iterates through the fetched
Courseentries and renders aCourseCardpartial view for each one, promoting reusability and separation of concerns.
razor
// File: TheExampleApp/Pages/Courses.cshtml
<div class="grid-list">
@if (Model.Courses == null || Model.Courses.Count == 0)
{
@Html.Partial("NoContent")
}
else
{
@foreach (var course in Model.Courses)
{
<div class="grid-list__item">
@Html.Partial("CourseCard", course)
</div>
}
}
</div>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
For a deeper understanding of how courses and categories are modeled in Contentful and handled within the application, see the Course Management documentation.
Switching locales
The application is built with internationalization (i18n) support from the ground up. It includes resource files for English (en-US.json) and German (de-DE.json) to localize UI strings.
More importantly, the selected locale is passed to the Contentful API to fetch content in the correct language. The locale is retrieved from the user's session and used in the query builder, as seen in Index.cshtml.cs:
csharp
// File: TheExampleApp/Pages/Index.cshtml.cs
// The locale is retrieved from the session or defaults to the server's current culture.
var locale = HttpContext?.Session?.GetString(Startup.LOCALE_KEY) ?? CultureInfo.CurrentCulture.ToString();
var queryBuilder = QueryBuilder<Layout>.New
// ...
.LocaleIs(locale);1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
A UI element (typically in the site's header or footer) allows the user to switch the active language, which updates the Startup.LOCALE_KEY value in the session and triggers a page reload to fetch the localized content. For more details on the i18n implementation, please visit the Internationalization page.
Preview vs. delivery API
Contentful provides two primary APIs for content retrieval:
| API | Purpose | Content |
|---|---|---|
| Delivery API (CDA) | For production use. Delivers published, publicly available content. It is highly available and cached via CDN. | Published entries only. |
| Preview API (CPA) | For development and editorial use. Delivers both draft and published content for previewing changes before they go live. | Draft and published entries. |
The application can be configured to use either API. This is controlled by the UsePreviewApi boolean in appsettings.json or can be set via query parameters in the URL (e.g., ?api=cpa for Preview API or ?api=cda for Delivery API). When using your own write-enabled space, switching to the Preview API allows you to see unpublished drafts and pending changes directly within the application.
Furthermore, enabling "Editorial Features" (via the /settings page or the editorial_features=enabled query parameter) enhances the preview experience by adding "Edit" links and status indicators to content, providing a seamless bridge to the Contentful web app for content editors.
Next steps
You have successfully run the application and explored its basic features. To continue, we recommend exploring the following documentation for a deeper understanding of the application's architecture and features:
- Installation: A comprehensive guide covering all prerequisites and setup steps.
- Contentful Setup: Detailed instructions on how to create your own Contentful space and connect it to the application for a full read/write experience.
- Course Management: An in-depth look at how the "Course" and "Category" content types are modeled and rendered.
- Internationalization: A guide to the application's multi-language support and localization strategy.