Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 40 additions & 17 deletions .github/clean-headless-api.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,23 +29,7 @@ builder.CreateUmbracoBuilder()

Once the Content Delivery API is enabled, the next step is to rebuild the Delivery API content index **DeliveryApiContentIndex**. This can be done using the Examine Management dashboard in the Settings section of the Umbraco Backoffice.

## Next.js Revalidation

To enable automatic revalidation of content in Next.js applications, configure the following in your `appsettings.json`:

```json
{
"NextJs": {
"Revalidate": {
"Enabled": true,
"WebHookUrls": "[\"http://localhost:3000/api/revalidate\"]",
"WebHookSecret": "SOMETHING_SECRET"
}
}
}
```

**Note**: Update the `WebHookUrls` to match your Next.js application's URL.

## Headless Frontend Example

Expand All @@ -55,8 +39,27 @@ Phil Whittaker has created a complete headless Next.js frontend for this starter

This implementation demonstrates how to use the Clean starter kit as a headless CMS with a modern Next.js frontend.

**Note for Umbraco 18**: DeliveryApi configuration must also include `GenerateContentTypeSchemas`:


```json
{
"Umbraco": {
"CMS": {
"DeliveryApi": {
"Enabled": true,
"OpenApi": {
"GenerateContentTypeSchemas": true
}
}
}
}
}
```

---


## API Endpoints

The Clean starter kit provides a suite of custom API endpoints for common functionality:
Expand All @@ -69,10 +72,30 @@ The Clean starter kit provides a suite of custom API endpoints for common functi

Explore and test the API endpoints using the built-in Swagger UI:

**URL**: `/umbraco/swagger/index.html?urls.primaryName=Clean%20starter%20kit`
**Umbraco 18+**: `/umbraco/openapi/`

**Earlier versions**: `/umbraco/swagger/`

This provides interactive documentation for all available API endpoints, including request/response schemas and the ability to test endpoints directly from the browser.

## Next.js Revalidation

To enable automatic revalidation of content in Next.js applications, configure the following in your `appsettings.json`:

```json
{
"NextJs": {
"Revalidate": {
"Enabled": true,
"WebHookUrls": "[\"http://localhost:3000/api/revalidate\"]",
"WebHookSecret": "SOMETHING_SECRET"
}
}
}
```

**Note**: Update the `WebHookUrls` to match your Next.js application's URL.

---

## Related Documentation
Expand Down
4 changes: 2 additions & 2 deletions template/Clean.Blog/Controllers/PackageController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ namespace Umbraco.Cms.Api.Management.Controllers.Package.Created;
[Route("api/v{version:apiVersion}/package")]
[ApiVersion("1.0")]
[ApiExplorerSettings(GroupName = "Package")]
[MapToApi("clean-starter")]
[MapToApi("clean-starter-admin")]
[ApiController]
public class PackageController : CreatedPackageControllerBase
{
Expand Down Expand Up @@ -175,4 +175,4 @@ public async Task<IActionResult> GetPackage(CancellationToken cancellationToken,
return PackageOperationStatusResult(result.Status);
}
}
}
}
43 changes: 0 additions & 43 deletions template/Clean.Blog/Controllers/TestController.cs

This file was deleted.

1 change: 1 addition & 0 deletions template/Clean.Headless/Controllers/ContactV1Controller.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ namespace Clean.Headless.Controllers;
[Route("api/v{version:apiVersion}/contact")]
[ApiVersion("1.0")]
[ApiExplorerSettings(GroupName = "Contact")]
[Tags("Contact")]
[MapToApi("clean-starter")]
[ApiController]
public class ContactApiV1Controller : ControllerBase
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ namespace Clean.Headless.Controllers;
[ApiVersion("1.0")]
[MapToApi("clean-starter")]
[ApiExplorerSettings(GroupName = "Translation")]
[Tags("Translation")]
[ApiController]
public class DictionaryApiV1Controller(
IDictionaryItemService dictionaryItemService,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ namespace Clean.Headless.Controllers;
[Route("api/v{version:apiVersion}/search")]
[ApiVersion("1.0")]
[ApiExplorerSettings(GroupName = "Search")]
[Tags("Search")]
[MapToApi("clean-starter")]
[ApiController]
public class SearchApiV1Controller : ControllerBase
Expand Down
11 changes: 11 additions & 0 deletions template/Clean.Headless/Startup/CleanStarterOpenApiExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc.Controllers;
using Microsoft.AspNetCore.OpenApi;
using Microsoft.Extensions.DependencyInjection;
using Umbraco.Cms.Api.Common.Attributes;
using Umbraco.Cms.Api.Common.DependencyInjection;

namespace Clean.Headless.Startup;
Expand All @@ -14,6 +17,14 @@ public static IServiceCollection AddCleanStarterOpenApi(this IServiceCollection
{
services.AddOpenApi(DocumentName, options =>
{

// Include DictoryApiV1Controller, SearchApiV1Controller and ContactApiV1Controller in the OpenAPI document
options.ShouldInclude = apiDescription =>
apiDescription.ActionDescriptor is ControllerActionDescriptor controllerActionDescriptor
&& controllerActionDescriptor.EndpointMetadata
.OfType<MapToApiAttribute>()
.Any(attribute => attribute.ApiName == DocumentName);

options.AddDocumentTransformer((document, _, _) =>
{
document.Info.Title = DisplayName;
Expand Down
Loading