Tuesday, October 29, 2024

Sitecore Content Hub - Best practices


When working with Sitecore Content Hub, adopting best practices can significantly enhance your content management efficiency and overall user experience. First, establish a clear content governance structure to define roles and responsibilities, ensuring that content creation, approval, and publishing processes are streamlined. Utilize consistent metadata tagging to improve content discoverability and organization, enabling users to quickly find relevant assets. Regularly audit and update your content to maintain its relevance and accuracy, and implement a robust version control system to track changes and maintain historical records. Finally, leverage automation features to simplify repetitive tasks, allowing your team to focus on strategic content initiatives. By following these best practices, you can optimize your use of Sitecore Content Hub and drive more impactful content outcomes.

Asset Type and Media Type:

Asset Type is manual assigned value. It triggers CH built-in tasks:

• Trigger Vision

• Trigger AI

• Trigger extract archive

Asset Media is automatically assigned based on file extension. It drives Media

Processing content flow:

• Image

• Vector

• Documents

• Audio

• Video

• Archives


Custom Media Processing:



Links:



Public Link:

• Public: no authentication required.

• Do not depend on Content Hub Portal availability

• Integrated with CDN

• Distributed

• Works on asset level

• Custom URL path

• Can specify expiration (could be cached up to 10 minutes)

• Based on rendition

• Can apply transformation (t)

• Image merging (b)

• Force download (download=true)

• Has version (v)


Gateway Link:

• Authenticated

• Depends on availability MCH

• Predictable format: .../api/gateway/id/thumbnail

• Works on asset level

• Automatically take master file if no rendition is specified

• Depends on access rights of users


Signed Delivery Link:

• Public

• Timebombed (20 min)

• Contain user-info for auditing

• Hash for security reasons. Changes on each request.

• Do not depend on Content Hub Portal availability

• Distributed


Graph Build:

• Avoid performing multiple heavy operations at the same time. Consider doing one heavy

operation at a time.

• If there is a need to perform heavy operations, please consider performing the operation

when the environment is not expected to be heavily used by users and you can afford to

wait for the graph to rebuild.

• For data ingestions, consider uploading data in smaller batches. For example, if you plan to

upload 400K assets, consider uploading it in four batches of 100K assets. This way you can

you can verify the changes more quickly, and the processing resources utilization goes

back to normal earlier after each batch processing.


Trigger/Action/Script:

• Do not use In process trigger if not necessary, e.g. validation script

• Do use Objective and Conditions to limit the trigger conditions

• Break down single complicated trigger conditions to multiple triggers

• Do not create nested trigger conditions

• Use API Call or Service Bus Action to Azure Function for complicated code

logic

• Regular review the triggers and remove the unused ones


Throttling:

• Make sure that a rate limit of 15 calls per second (per API integration user) is respected.

• Use the WebSDK, which has embedded throttling, over the REST API (for which you have to code the

retry mechanism yourself).

• If required, modify the Content Hub WebSDK built-in retry policy. By default, any call returning an

HTTP 429 response is retried nine times. You can modify the RetryCount property of the retry policy as

required.

• Establish a retry after logic when you use the API. Group your requests into batches and take action

when you receive an HTTP 429 response.

• Create dedicated API users for each integration to detect which one is overloading your platform or

generating errors. If you have a sizeable integration (with multiple components), divide it into blocks

and create a dedicated API user per block.


Users & User group policies:

• You should not assign a user to more than ten user groups.

• Avoid create too many rules in a group policy. Do not define duplicate rules and

permissions.

• Keep the number of different renditions limited in media processing to avoid generating

many renditions.

• Provide the fewest standard renditions that fit the most downstream use cases possible,

and leverage public links with transformations as much as possible.

• Do not turn on Image AI or Video AI if they are no in use


                                                        Happy Learning!

Restrict uploading Video and Audio files in Sitecore Media Library based on Mime Type

 Restrict uploading Video and Audio files in Media Library based on Mime Type/Restrict uploading zip file which contains Video and Audio files in Media Library based on Mime Type:

By default, Sitecore allows the user to upload multiple types of files in the media library. This blog will guide you to restrict the content author not to upload specific file types(Ex. audio, video). Please follow the steps to create the custom pipeline processor to apply the restriction from Sitecore UI. 

Create a pipeline processor :

using Sitecore.Configuration;

using Sitecore.Diagnostics;

using Sitecore.Pipelines.Upload;

using Sitecore.Zip;

using System;

using System.Collections.Generic;

using System.Collections.Specialized;

using System.IO;

using System.IO.Compression;

using System.Linq;

using System.Web;

namespace SampleWebsite.Web.Foundation.Pipelines.Pipelines

{

    public class CheckFileTypePipeline : UploadProcessor

    {

        private bool _isAllowed;

        private string _extensions;

        public CheckFileTypePipeline(string blocked)

        {

            if (string.IsNullOrEmpty(blocked))

                return;

            this._isAllowed = false;

            this._extensions = blocked.Replace(" ", "").ToLower();

        }

        public void Process(UploadArgs args)

        {

            Assert.ArgumentNotNull((object)args, nameof(args));

            if (string.IsNullOrEmpty(this._extensions))

                return;

            List<string> stringList = this.PrepareExtensions(this._extensions);

            foreach (string file1 in (NameObjectCollectionBase)args.Files)

            {

                HttpPostedFile file2 = args.Files[file1];

                if (!string.IsNullOrEmpty(file2.FileName))

                {

                    if (UploadProcessor.IsUnpack(args,file2))

                      {

                        ZipReader zipReader = new ZipReader(file2.InputStream);

                        try

                        {

                            foreach (ZipEntry entry in zipReader.Entries)

                            {

                                string mimeTypef = MimeMapping.GetMimeMapping(entry.Name);

                                bool flag = stringList.Any(x => mimeTypef.Contains(x));

                                if ((!this._isAllowed || !flag) && (!this._isAllowed && flag || this._isAllowed && !flag))

                                {                                   

                                HttpContext.Current.Response.Write("<script type=\"text/JavaScript\">alert(\"Uploading files with " + mimeTypef + " as type is restricted\");</script>");

                                   Log.Audit(string.Format("Upload restricted: {0}", (object)entry.Name), (object)this);

                                    new Done().Process(args);

                                   args.AbortPipeline();

                                    return;

                                }

                            }

                        }

                        finally

                        {                           

                            file2.InputStream.Position = 0L;

                        }

                    }

                    string mimeTypef2 = MimeMapping.GetMimeMapping(file2.FileName);

                    bool flag1 = stringList.Any(x => mimeTypef2.Contains(x));

                   if ((!this._isAllowed || !flag1) && (!this._isAllowed && flag1 || this._isAllowed && !flag1))

                        {                           

                        HttpContext.Current.Response.Write("<script type=\"text/JavaScript\">alert(\"Uploading files with " + mimeTypef2 + " as file type is restricted\");</script>");

                            Log.Audit(string.Format("Upload restricted: {0}", (object)file2.FileName), (object)this);

                            new Done().Process(args);                           

                            args.AbortPipeline();

                            break;

                        }

                    }

            }

        }

        private List<string> PrepareExtensions(string csvExtensions)

        {

            string[] strArray = csvExtensions.Split(',');

            List<string> stringList = new List<string>();

            foreach (string str in strArray)

                stringList.Add(str);

            return stringList;

        }

    }

}


Create a patch Config file :

<?xml version="1.0" encoding="utf-8"?>

<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">

  <sitecore>

    <processors>

      <uiUpload>

        <processor mode="on" type=" SmpleSite.Web.Foundation.Pipelines.Pipelines.CheckFileType, SmpleSite.Web.Foundation.Pipelines" patch:before="*[1]">

          <param desc="Blocked filetypes (comma separated)">video,audio</param>

        </processor>

      </uiUpload>

    </processors>

  </sitecore>

</configuration>


Let's deploy these files to the website's root folder and give it a try.

 Go to Media library and try to upload a file and then click on “Choose File”.


Click on Upload




Final result: You see a restriction message on the pop-up.



                        
                                                            Happy learning!

Saturday, October 26, 2024

Sitecore JSS using NextJs - Helix architecture setup

 Setting up Sitecore JSS with Next.js using the Helix architecture involves a structured approach to ensure scalability and maintainability. Begin by organizing your project into clear layers: presentation, data, and content, in alignment with Helix principles. Utilize Next.js for server-side rendering and static site generation, which enhances performance and SEO. Implement Sitecore’s Headless services to seamlessly fetch content through GraphQL APIs, enabling dynamic content delivery. Structure your components to be reusable and modular, following the atomic design methodology, and ensure that styles and assets are handled consistently across your application. Incorporate Sitecore’s Layout Service to manage rendering logic and optimize the user experience. Finally, set up CI/CD pipelines to automate deployments, ensuring that your development workflow remains efficient and aligned with best practices. By adhering to these guidelines, you can effectively leverage Sitecore JSS with Next.js to create powerful, headless web applications.

This blog can help you to work with Sitecore CMS and set up the helix architecture with Next JSS. 

The following steps will be used to set up the helix architecture for the Next JSS application. These guidelines are applicable to Sitecore 10.3. 

1. Create the project solution by referring to the following blog. You can name your solution anything you like.

https://sitecoreknowledgehub.blogspot.com/2023/03/sitecore-jss-next-jss-local-environment.html

2. The output of step #1 is shown below.


3. Create  the main Helix folder structure like below,



4. Create a module.json file inside the feature folder and update the JSON file with the item paths.




5. Move NextJs framework code/libraries and platform project inside the project folder.


5. Create Foundation projects to maintain common features, helpers,..etc,



6. So far we created the Helix folder structure and changed the existing structure that we get from the getting started template. In order to make the application up and running, please make the following changes in the respective files.

Change the push location path inside file- up.ps1.


Navigate to \run\sitecore-xp0 and update the .env file as per your system configuration.


Update the folder paths (mention paths where the module.json file is located) inside file -\sitecore.json.


Go to file - \dockerfile and change the platform project path.


Change the NextJs source path inside the file -\run\sitecore-xp0\docker-compose.override.yml


7. Finally run the command- docker-compose up -d. Your JSS app should work with Helix setup.



                                                                    Happy learning!

How to Create a Public Link Using the Sitecore Content Hub REST API

Creating a public link using the Sitecore Content Hub REST API is a straightforward process that enables you to share content externally whi...