Skip to content

Integrating Skybrud.Umbraco.Redirects in Nikcio.UHeadless

The Nikcio.UHeadless package provides a way to integrate the Skybrud.Umbraco.Redirects package in your Umbraco Headless project. This allows you to query for content like you would usually do but with the added benefit of getting redirect information from SKybrud.Umbraco.Redirects.

Example

Step 1: Install the Skybrud.Umbraco.Redirects package

First, you need to install the Skybrud.Umbraco.Redirects package. You can do this by running the following command in the Package Manager Console:

Terminal window
Install-Package Skybrud.Umbraco.Redirects

Step 2: Create a query class

using HotChocolate;
using HotChocolate.Resolvers;
using HotChocolate.Types;
using Nikcio.UHeadless;
using Nikcio.UHeadless.ContentItems;
using Nikcio.UHeadless.Defaults.ContentItems;
using Skybrud.Umbraco.Redirects.Models;
using Skybrud.Umbraco.Redirects.Services;
[ExtendObjectType(typeof(HotChocolateQueryObject))]
public class SkybrudRedirectsExampleQuery : ContentByRouteQuery
{
[GraphQLName("skybrudRedirectsExampleQuery")]
public override Task<ContentItem?> ContentByRouteAsync(
IResolverContext resolverContext,
[GraphQLDescription("The route to fetch. Example '/da/frontpage/'.")] string route,
[GraphQLDescription("The base url for the request. Example: 'https://localhost:4000'. Default is the current domain")] string baseUrl = "",
[GraphQLDescription("The context of the request.")] QueryContext? inContext = null)
{
return base.ContentByRouteAsync(resolverContext, route, baseUrl, inContext);
}
protected override async Task<ContentItem?> CreateContentItemFromRouteAsync(IResolverContext resolverContext, string route, string baseUrl)
{
ArgumentNullException.ThrowIfNull(resolverContext);
ArgumentNullException.ThrowIfNull(baseUrl);
IRedirectsService redirectService = resolverContext.Service<IRedirectsService>();
var uri = new Uri($"{baseUrl.TrimEnd('/')}{route}");
IRedirect? redirect = redirectService.GetRedirectByUri(uri);
if (redirect != null)
{
IContentItemRepository<ContentItem> contentItemRepository = resolverContext.Service<IContentItemRepository<ContentItem>>();
string redirectUrl = redirect.Destination.FullUrl;
if (redirect.ForwardQueryString)
{
redirectUrl = redirectUrl.TrimEnd('/') + uri.Query;
}
return contentItemRepository.GetContentItem(new ContentItem.CreateCommand()
{
PublishedContent = null,
ResolverContext = resolverContext,
Redirect = new()
{
IsPermanent = redirect.IsPermanent,
RedirectUrl = redirectUrl,
},
StatusCode = redirect.IsPermanent ? StatusCodes.Status301MovedPermanently : StatusCodes.Status307TemporaryRedirect,
});
}
return await base.CreateContentItemFromRouteAsync(resolverContext, route, baseUrl).ConfigureAwait(false);
}
}

This query class extends the ContentByRouteQuery query and overrides the CreateContentItemFromRouteAsync method. This method is called when a content item is fetched by route. In this method, we get the IRedirectsService from the IResolverContext and fetch the redirect for the route. If a redirect is found, we create a new ContentItem with the redirect information.

Step 3: Add the query to the UHeadless configuration

.AddUHeadless(options =>
{
options.AddQuery<SkybrudRedirectsExampleQuery>();
})

Step 4: Query the content

Now you can query the content by route and get the redirect information:

query {
skybrudRedirectsExampleQuery(baseUrl: "", route: "/") {
redirect {
isPermanent
redirectUrl
}
}
}

This will return the redirect information if a redirect is found for the route. If no redirect is found, the content item will be fetched as usual.