<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Untitled Publication]]></title><description><![CDATA[Untitled Publication]]></description><link>https://saadpatel.hashnode.dev</link><generator>RSS for Node</generator><lastBuildDate>Tue, 01 Sep 2026 23:23:29 GMT</lastBuildDate><atom:link href="https://saadpatel.hashnode.dev/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[Easily set up multi-theming in Sitecore JSS using Next.js and Tailwind CSS (Part 2)]]></title><description><![CDATA[In this article, we will explore the implementation of multiple themes within a single source code. Our approach to achieving multi-theming relies on React's context feature. To accomplish this, we encapsulate the entire application within the theme ...]]></description><link>https://saadpatel.hashnode.dev/easily-set-up-multi-theming-in-sitecore-jss-using-nextjs-and-tailwind-css-part-2</link><guid isPermaLink="true">https://saadpatel.hashnode.dev/easily-set-up-multi-theming-in-sitecore-jss-using-nextjs-and-tailwind-css-part-2</guid><category><![CDATA[multitheming]]></category><category><![CDATA[Sitecore]]></category><category><![CDATA[Sitecore JSS]]></category><category><![CDATA[Tailwind CSS]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[React]]></category><category><![CDATA[webdevelopment]]></category><category><![CDATA[headless cms]]></category><category><![CDATA[headless]]></category><category><![CDATA[Frontend Development]]></category><category><![CDATA[Next.js]]></category><dc:creator><![CDATA[Saad Patel]]></dc:creator><pubDate>Thu, 08 Feb 2024 08:28:10 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1707383512862/92604b6f-1299-46c7-b8a4-fa2d77256f5a.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In this article, we will explore the implementation of multiple themes within a single source code. Our approach to achieving multi-theming relies on React's context feature. To accomplish this, we encapsulate the entire application within the theme context.</p>
<div data-node-type="callout">
<div data-node-type="callout-emoji">ℹ</div>
<div data-node-type="callout-text">This article assumes that theme configuration is already done. If not then please read to <a target="_blank" href="https://saadpatel.hashnode.dev/mastering-theme-diversity-a-step-by-step-guide-to-implementing-multiple-themes-on-sitecore-jss-part-1">Configure multi-theming</a> configure theme.</div>
</div>

<h2 id="heading-initiate-multi-theming">Initiate multi theming</h2>
<p>Before delving into the practical application of multi-theming, there's a preliminary step we need to take.</p>
<p>Head over to <code>src/Layout.tsx</code> and import the <code>useTheme</code> hook we crafted in the <code>ThemeContext.tsx</code> file. Refer code snippet below to get more idea.</p>
<pre><code class="lang-typescript"><span class="hljs-comment">//Layout.tsx</span>
<span class="hljs-keyword">import</span> { useTheme } <span class="hljs-keyword">from</span> <span class="hljs-string">'lib/context/ThemeContext'</span>;

<span class="hljs-keyword">const</span> Layout: React.FC&lt;LayoutProps&gt; = ({ layoutData }: LayoutProps): JSX.Element =&gt; {
  <span class="hljs-comment">//...Rest of the code</span>
  <span class="hljs-keyword">const</span> { themeName } = useTheme();
  <span class="hljs-comment">//...Rest of the code</span>
}
</code></pre>
<p><code>useTheme</code> will give us the <code>themeName</code> variable which represents the current theme for the given site.</p>
<p>We need to add the current theme name as a class to a wrapper div that encompasses the entire application. Refer to line #<code>9</code> in code snippet below to get more idea.</p>
<pre><code class="lang-typescript"><span class="hljs-comment">//Layout.tsx</span>
<span class="hljs-keyword">import</span> { useTheme } <span class="hljs-keyword">from</span> <span class="hljs-string">'lib/context/ThemeContext'</span>;

<span class="hljs-keyword">const</span> Layout: React.FC&lt;LayoutProps&gt; = ({ layoutData }: LayoutProps): JSX.Element =&gt; {
  <span class="hljs-comment">//...Rest of the code</span>
  <span class="hljs-keyword">const</span> { themeName } = useTheme();
  <span class="hljs-comment">//...Rest of the code</span>

  <span class="hljs-keyword">return</span> (
    &lt;div className={classNames(mainClassPageEditing, themeName)}&gt;
      &lt;header&gt;
        {<span class="hljs-comment">/* Render placeholder for header */</span>}
        &lt;div id=<span class="hljs-string">"header"</span>&gt;{route &amp;&amp; &lt;Placeholder name=<span class="hljs-string">"headless-header"</span> rendering={route} /&gt;}&lt;/div&gt;
      &lt;/header&gt;
      &lt;main&gt;
        {<span class="hljs-comment">/* Render placeholder for main content */</span>}
        &lt;div id=<span class="hljs-string">"content"</span>&gt;{route &amp;&amp; &lt;Placeholder name=<span class="hljs-string">"headless-main"</span> rendering={route} /&gt;}&lt;/div&gt;
      &lt;/main&gt;
      &lt;footer&gt;
        {<span class="hljs-comment">/* Render placeholder for footer */</span>}
        &lt;div id=<span class="hljs-string">"footer"</span>&gt;{route &amp;&amp; &lt;Placeholder name=<span class="hljs-string">"headless-footer"</span> rendering={route} /&gt;}&lt;/div&gt;
        &lt;AlgoliaCrawler layoutData={layoutData} /&gt;
      &lt;/footer&gt;
    &lt;/div&gt;
  );
}
</code></pre>
<div data-node-type="callout">
<div data-node-type="callout-emoji">ℹ</div>
<div data-node-type="callout-text">Typically we need to append the theme name as a class to the div whose children are intended to adopt the theme. In our scenario, it should be the div that encapsulates the entire application.</div>
</div>

<div data-node-type="callout">
<div data-node-type="callout-emoji">💡</div>
<div data-node-type="callout-text">If you want to dig more into how <a target="_blank" href="https://www.npmjs.com/package/tailwindcss-themer">npm: tailwindcss-themer</a> works, I recommend exploring it by consulting the documentation.</div>
</div>

<h2 id="heading-steps-to-use-multi-theming">Steps to use multi-theming</h2>
<p>Follow below steps to create a component which can use multi theme. We’ll create a component named with <code>HeroTwoColumn</code> in our example.</p>
<ol>
<li><p>Create 2 files one is component and second is theme file.</p>
<ul>
<li><p><code>HeroTwoColumn.tsx</code></p>
<pre><code class="lang-typescript">  <span class="hljs-comment">//HeroTwoColumn.tsx</span>

  <span class="hljs-keyword">import</span> { useTheme } <span class="hljs-keyword">from</span> <span class="hljs-string">'lib/context/ThemeContext'</span>;
  <span class="hljs-keyword">import</span> { HeroTwoColumnTheme } <span class="hljs-keyword">from</span> <span class="hljs-string">'./HeroTwoColumn.theme'</span>;

  <span class="hljs-keyword">export</span> <span class="hljs-keyword">type</span> HeroTwoColumnProps = Feature.EnterpriseWeb.Components.Hero.HeroTwoColumn;

  <span class="hljs-keyword">const</span> HeroTwoColumn = <span class="hljs-function">(<span class="hljs-params">props: HeroTwoColumnProps</span>) =&gt;</span> {
    <span class="hljs-keyword">const</span> { themeName, themeData } = useTheme(HeroTwoColumnTheme);

      <span class="hljs-keyword">if</span> (!props.fields) <span class="hljs-keyword">return</span> <span class="hljs-literal">null</span>;

      <span class="hljs-keyword">return</span> (
        &lt;Component variant=<span class="hljs-string">"1g"</span> dataComponent=<span class="hljs-string">"hero/herotwocolumn"</span> gap=<span class="hljs-string">"!gap-xxxs md:gap-s"</span> {...props}&gt;
          {themeName === <span class="hljs-string">'primary'</span> &amp;&amp; (
            &lt;div className=<span class="hljs-string">"col-span-12 md:col-span-1"</span>&gt;
              &lt;span className=<span class="hljs-string">"inline-block h-[3px] w-1 bg-primary md:w-full"</span>&gt;&lt;/span&gt;
            &lt;/div&gt;
          )}

          &lt;div className={<span class="hljs-string">`col-span-12 <span class="hljs-subst">${themeName === <span class="hljs-string">'primary'</span> ? <span class="hljs-string">'md:col-span-5'</span> : <span class="hljs-string">'md:col-span-6'</span>}</span>`</span>}&gt;
            &lt;Headline useTag=<span class="hljs-string">"h1"</span> classes={themeData.classes.headlineClass} {...props} /&gt;
          &lt;/div&gt;

          &lt;div className=<span class="hljs-string">"col-span-12 md:col-span-6"</span>&gt;
            &lt;Subheadline useTag=<span class="hljs-string">"h2"</span> classes={themeData.classes.subheadlineClass} {...props} /&gt;
            &lt;BodyCopy classes={themeData.classes.bodyClass} {...props} /&gt;
            &lt;ButtonGroup classes={themeData.classes.buttonGroupClass} {...props} /&gt;
          &lt;/div&gt;
        &lt;/Component&gt;
    );
  }
</code></pre>
</li>
<li><p><code>HeroTwoColumn.theme.ts</code></p>
<pre><code class="lang-typescript">  <span class="hljs-comment">//HeroTwoColumn.theme.ts</span>

  <span class="hljs-keyword">import</span> { ThemeFile } <span class="hljs-keyword">from</span> <span class="hljs-string">'lib/context/ThemeContext'</span>;

  <span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> HeroTwoColumnTheme: ThemeFile = {
    primary: {
      classes: {
        headlineClass: <span class="hljs-string">'text-sm-1 lg:text-1 font-heavy mb-s'</span>,
        subheadlineClass: <span class="hljs-string">'text-sm-m 1g:text-m font-medium mb-s'</span>,
        bodyClass: <span class="hljs-string">'text-body text-dark-gray font-regular mb-s'</span>,
        buttonGroupClass: {
          wrapper: <span class="hljs-string">'flex-col'</span>,
          cta1Classes: <span class="hljs-string">'mr-2 mb-m md:mb-0'</span>,
          cta2Classes: <span class="hljs-string">'ml-xs md:ml-0 px-s md:px-0'</span>,
        },
      },
    },
    secondary: {
      classes: {
        headlineClass: <span class="hljs-string">'text-sm-m lg:text-1 font-medium'</span>,
        subheadlineClass: <span class="hljs-string">'text-sm-m 1g:text-1 font-extra-light'</span>,
        bodyClass: <span class="hljs-string">'text-body text-dark-gray font-regular mb-xxs'</span>,
        buttonGroupClass: {
          wrapper: <span class="hljs-string">'flex-col md:items-center'</span>,
          cta1Classes: <span class="hljs-string">'mr-2'</span>,
          cta2Classes: <span class="hljs-string">'my-s md:my-0'</span>,
        },
      },
    },
  };
</code></pre>
</li>
</ul>
</li>
<li><p><code>HeroTwoColumn</code> contains of headline, subheadline, body and CTA elements. So, theme file contains classes as per the given elements in the component.</p>
</li>
<li><p>Import <code>useTheme</code> context and pass the component’s theme object imported from theme file in it. Please refer line #<code>7</code> in <code>HeroTwoColumn.tsx</code>.</p>
</li>
<li><p><code>useTheme</code> will return two variables -</p>
<p> a. <code>themeName</code> - contains current theme name.</p>
<p> b. <code>themeData</code> - contains the theme object from theme file.</p>
</li>
<li><p>If current theme is <code>primary</code>, Component will be rendered using <code>primary</code> object from theme file.</p>
</li>
<li><p>For example if we think about <code>Headline</code>, We’ve passed <code>themeData.classes.headlineClass</code> in order to style it. Please refer line #<code>20</code> in <code>HeroTwoColumn.tsx</code>. If current theme is <code>primary</code> it’ll refer to <code>headlineClass</code> key at line #<code>6</code>. If current theme is <code>secondary</code> it’ll refer to <code>headlineClass</code> key at line #<code>18</code> in <code>HeroTwoColumn.theme.ts</code>.</p>
</li>
</ol>
<p>In summary, we've effectively implemented multi-theming in our JSS application by following above steps. By leveraging this feature, we've enhanced developer experience while ensuring adaptability and scalability for future improvements.</p>
<h2 id="heading-extra-notes">Extra notes</h2>
<div data-node-type="callout">
<div data-node-type="callout-emoji">⚠</div>
<div data-node-type="callout-text">If you're utilizing the latest version of JSS, ensure to create the <code>HeroTwoColumn.theme.tsx</code> file outside the <code>/src/components</code> folder. JSS treats all files within <code>/src/components</code> as authorable components, and placing <code>HeroTwoColumn.theme.ts</code> inside it would register it as a component in the JSS ecosystem.</div>
</div>

<div data-node-type="callout">
<div data-node-type="callout-emoji">💡</div>
<div data-node-type="callout-text">In case if we require advanced theming, We can return the function instead of returning the direct theme object. Please refer below code.</div>
</div>

<pre><code class="lang-typescript"><span class="hljs-comment">//Sample theme file for advance theming</span>

<span class="hljs-keyword">import</span> classNames <span class="hljs-keyword">from</span> <span class="hljs-string">'classnames'</span>;
<span class="hljs-keyword">import</span> { ThemeFile, ThemeName } <span class="hljs-keyword">from</span> <span class="hljs-string">'lib/context/ThemeContext'</span>;
<span class="hljs-keyword">import</span> { BorderStyle, TextAlignment } <span class="hljs-keyword">from</span> <span class="hljs-string">'./SectionHeadline'</span>;

<span class="hljs-keyword">const</span> primaryHeadlineClasses = <span class="hljs-string">'text-s md:text-m font-heavy pb-xs mb-s'</span>;

<span class="hljs-keyword">const</span> secondaryHeadlineClasses = <span class="hljs-string">'text-m md:text-l font-extra-light pb-xs mb-s'</span>;

<span class="hljs-keyword">const</span> getBorderClasses = <span class="hljs-function">(<span class="hljs-params">theme: ThemeName, borderStyle: BorderStyle</span>) =&gt;</span> {
  <span class="hljs-keyword">if</span> (borderStyle !== <span class="hljs-string">'default'</span>) {
    <span class="hljs-keyword">let</span> borderClasses = theme === <span class="hljs-string">'primary'</span> ? <span class="hljs-string">'border-b-6 '</span> : <span class="hljs-string">'border-b-3 '</span>;

    <span class="hljs-keyword">switch</span> (borderStyle) {
      <span class="hljs-keyword">case</span> <span class="hljs-string">'dark'</span>:
        borderClasses += theme === <span class="hljs-string">'primary'</span> ? <span class="hljs-string">'border-primary'</span> : <span class="hljs-string">'border-secondary'</span>;
        <span class="hljs-keyword">break</span>;
      <span class="hljs-keyword">case</span> <span class="hljs-string">'light'</span>:
        borderClasses += theme === <span class="hljs-string">'primary'</span> ? <span class="hljs-string">'border-light-gray'</span> : <span class="hljs-string">'border-gray'</span>;
        <span class="hljs-keyword">break</span>;
      <span class="hljs-keyword">default</span>:
        <span class="hljs-keyword">break</span>;
    }

    <span class="hljs-keyword">return</span> borderClasses;
  }
  <span class="hljs-keyword">return</span> <span class="hljs-string">''</span>;
};

<span class="hljs-keyword">const</span> getDynamicStyles = (
  theme: ThemeName,
  alignment: TextAlignment,
  borderStyle: BorderStyle
): <span class="hljs-function"><span class="hljs-params">string</span> =&gt;</span> {
  <span class="hljs-keyword">return</span> classNames(<span class="hljs-string">`text-<span class="hljs-subst">${alignment}</span>`</span>, getBorderClasses(theme, borderStyle));
};

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> SectionHeadlineTheme = (
  alignment: TextAlignment,
  borderStyle: BorderStyle
): <span class="hljs-function"><span class="hljs-params">ThemeFile</span> =&gt;</span> {
  <span class="hljs-keyword">return</span> {
    primary: {
      classes: {
        headlineContainer: classNames(
          primaryHeadlineClasses,
          getDynamicStyles(<span class="hljs-string">'primary'</span>, alignment, borderStyle)
        ),
      },
    },
    secondary: {
      classes: {
        headlineContainer: classNames(
          secondaryHeadlineClasses,
          getDynamicStyles(<span class="hljs-string">'secondary'</span>, alignment, borderStyle)
        ),
      },
    },
  };
};
</code></pre>
<div data-node-type="callout">
<div data-node-type="callout-emoji">ℹ</div>
<div data-node-type="callout-text">Keep in mind if the component’s layout or theming is same across the design we can always use the original way of applying classes. i.e. Directly apply the style in the component itself.</div>
</div>]]></content:encoded></item><item><title><![CDATA[Easily set up multi-theming in Sitecore JSS using Next.js and Tailwind CSS (Part 1)]]></title><description><![CDATA[Multi-theming refers to the ability to switch between different visual themes within an application. Themes can include changes to colors, typography, spacing, and other styling elements.
This article will provide step-by-step guidance on configuring...]]></description><link>https://saadpatel.hashnode.dev/easily-set-up-multi-theming-in-sitecore-jss-using-nextjs-and-tailwind-css-part-1</link><guid isPermaLink="true">https://saadpatel.hashnode.dev/easily-set-up-multi-theming-in-sitecore-jss-using-nextjs-and-tailwind-css-part-1</guid><category><![CDATA[multitheming]]></category><category><![CDATA[Sitecore]]></category><category><![CDATA[Sitecore JSS]]></category><category><![CDATA[Tailwind CSS]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[React]]></category><category><![CDATA[Web Development]]></category><category><![CDATA[headless cms]]></category><category><![CDATA[headless]]></category><category><![CDATA[Front-end Development]]></category><category><![CDATA[Frontend Development]]></category><category><![CDATA[Next.js]]></category><dc:creator><![CDATA[Saad Patel]]></dc:creator><pubDate>Thu, 08 Feb 2024 08:16:45 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1707383442596/3dd242c0-63f0-4200-91b7-0f1754657725.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Multi-theming refers to the ability to switch between different visual themes within an application. Themes can include changes to colors, typography, spacing, and other styling elements.</p>
<p>This article will provide step-by-step guidance on configuring multi-theming within a Sitecore JSS Headless/XM Cloud-based solution. The tutorial will specifically focus on utilizing NextJS and TailwindCSS to achieve this setup.</p>
<div data-node-type="callout">
<div data-node-type="callout-emoji">ℹ</div>
<div data-node-type="callout-text">While installing Sitecore NextJS SDK from <a target="_blank" href="https://doc.sitecore.com/xp/en/developers/hd/21/sitecore-headless-development/the-jss-app-initializer.html">The JSS app initializer</a> make sure to enable multisite addon when prompted.<strong>😄</strong></div>
</div>

<div data-node-type="callout">
<div data-node-type="callout-emoji">ℹ</div>
<div data-node-type="callout-text">This article is intended for individuals who are actively engaged in working on Sitecore JSS Headless. <strong>Feel absolutely liberated to give it a read if it tickles your curiosity! 😄</strong></div>
</div>

<p>The process is structured into two distinct phases, each dedicated to the meticulous task of establishing a multi-theme configuration and effectively harnessing its capabilities within the NextJS application. In this article, we'll look into configuring the multi-theming.</p>
<h2 id="heading-configure-multi-theming">Configure multi-theming</h2>
<p>Let's explore the process of configuring multi-theming and understand the steps involved in customizing and managing multiple themes.</p>
<h3 id="heading-theme-mappings">Theme mappings</h3>
<p>To begin, include the following variable in your environment variables. When referring to theme mapping, it essentially signifies the correlation between a specific site and its associated theme.</p>
<pre><code class="lang-javascript">NEXT_PUBLIC_THEME_MAPPINGS = {
  <span class="hljs-string">"primary"</span>:[<span class="hljs-string">"site1"</span>],
  <span class="hljs-string">"secondary"</span>:[<span class="hljs-string">"site2"</span>, <span class="hljs-string">"site3"</span>],
}
</code></pre>
<p>The <code>NEXT_PUBLIC_THEME_MAPPINGS</code> variable contains the theme mapping configurations. It's structured as an object, <strong>where the key represent the theme name, and the corresponding values are arrays of associated sites</strong>. It's important to note that the site names in the array should match those defined in Sitecore.</p>
<div data-node-type="callout">
<div data-node-type="callout-emoji">ℹ</div>
<div data-node-type="callout-text">It's essential to note that a single theme can be utilized by multiple sites. This is why we pass an array of sites, allowing for flexibility in associating the same theme with different sites.</div>
</div>

<div data-node-type="callout">
<div data-node-type="callout-emoji">⚠</div>
<div data-node-type="callout-text">Make sure to prefix theme mapping variable with <code>NEXT_PUBLIC</code> as these variables are needed at client-side. Make sure to prefix theme mapping variable with <code>NEXT_PUBLIC</code> as these variables are needed at client-side. If the same site is configured for multiple themes, it is noteworthy that the initial detected theme will be applied.</div>
</div>

<h3 id="heading-theme-context">Theme context</h3>
<h4 id="heading-create-theme-context">Create theme context</h4>
<p>We're using React context to make our themes work smoothly. First, we need to set up the context and organize the theme details in ThemeContext. Check the image below to see what ThemeContext is all about.</p>
<pre><code class="lang-typescript"><span class="hljs-comment">//ThemeContext.tsx</span>

<span class="hljs-keyword">import</span> { createContext, useContext } <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> ALL_THEMES = <span class="hljs-built_in">Object</span>.keys(<span class="hljs-built_in">JSON</span>.parse(process.env.NEXT_PUBLIC_THEME_MAPPINGS || <span class="hljs-string">'{}'</span>));

<span class="hljs-keyword">type</span> Themes = <span class="hljs-keyword">typeof</span> ALL_THEMES;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">type</span> ThemeName = Themes[<span class="hljs-built_in">number</span>];

<span class="hljs-keyword">export</span> <span class="hljs-keyword">type</span> ThemeFile = {
  [key <span class="hljs-keyword">in</span> ThemeName]: unknown;
};

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> ThemeContext = createContext&lt;ThemeName&gt;(ALL_THEMES[<span class="hljs-number">0</span>]);

<span class="hljs-comment">// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types</span>
<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> useTheme = <span class="hljs-function">(<span class="hljs-params">themeFile?: ThemeFile</span>) =&gt;</span> {
  <span class="hljs-keyword">const</span> themeName = useContext(ThemeContext);
  <span class="hljs-keyword">const</span> themeData = themeFile ? themeFile[themeName] : <span class="hljs-literal">undefined</span>;
  <span class="hljs-keyword">return</span> { themeName, themeData };
};
</code></pre>
<p>We can get mainly two variables from the context.</p>
<ol>
<li><p><code>themeName</code> - This tells us the name of the current theme.</p>
</li>
<li><p><code>themeData</code> - This provides the details of the theme linked to the current theme.</p>
</li>
</ol>
<div data-node-type="callout">
<div data-node-type="callout-emoji">ℹ</div>
<div data-node-type="callout-text">We'll explore the above variables further in the later sections.</div>
</div>

<h4 id="heading-use-theme-context">Use theme context</h4>
<p>Now that our theme context is set up, we just have to use it in the app. For this article, which concentrates on Sitecore's JSS NextJS solution, remember to wrap the entire app with the theme context. You can refer to it at <code>src/pages/_app.tsx</code></p>
<pre><code class="lang-typescript"><span class="hljs-comment">//_app.tsx</span>

<span class="hljs-keyword">import</span> { useState } <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;
<span class="hljs-keyword">import</span> config <span class="hljs-keyword">from</span> <span class="hljs-string">'temp/config'</span>;
<span class="hljs-keyword">import</span> { ThemeContext } <span class="hljs-keyword">from</span> <span class="hljs-string">'lib/context/ThemeContext'</span>;

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">App</span>(<span class="hljs-params">{ Component, pageProps }: AppProps&lt;SitecorePageProps&gt;</span>): <span class="hljs-title">JSX</span>.<span class="hljs-title">Element</span> </span>{
  <span class="hljs-keyword">const</span> { ...rest } = pageProps;
  <span class="hljs-keyword">const</span> sites = <span class="hljs-built_in">JSON</span>.parse(config.sites);

  <span class="hljs-keyword">const</span> currentSite = sites.find(
    <span class="hljs-function">(<span class="hljs-params">_</span>) =&gt;</span> _.name === pageProps.layoutData?.sitecore?.context?.site?.name
  );

  <span class="hljs-keyword">const</span> [site] = useState(currentSite || sites[<span class="hljs-number">0</span>]);

  <span class="hljs-keyword">return</span> (
    &lt;ThemeContext.Provider value={getTheme(site.name)}&gt;
      &lt;Component {...rest} /&gt;
    &lt;/ThemeContext.Provider&gt;
  );
}

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> App;
</code></pre>
<div data-node-type="callout">
<div data-node-type="callout-emoji">ℹ</div>
<div data-node-type="callout-text">The <code>config</code> will be generated automatically in <code>/temp</code> folder whenever the "bootstrap" command is invoked in the package.json file. The reference to <code>config.sites</code> corresponds to the SITES variable, and it's essential to ensure that this variable is defined as an environment variable.</div>
</div>

<div data-node-type="callout">
<div data-node-type="callout-emoji">ℹ</div>
<div data-node-type="callout-text">Don't worry about the <code>getTheme</code> function for now, We'll discuss it in the next section.</div>
</div>

<h3 id="heading-detect-current-theme">Detect current theme</h3>
<p>Having successfully set up the theme context, the next step involves detecting the current theme and assigning its value to the theme context.</p>
<p>In this part, we bring in the <code>getTheme</code> function. Its job is to figure out and give us the current theme based on the current site. Create a new file in <code>src/lib/multisite/theme-mapping.ts</code>.</p>
<p>This function takes the current site name as an argument. Using the NEXT_PUBLIC_THEME_MAPPINGS environment variable, it figures out and gives us the current theme. Take a look at the code snippet below for a quick understanding.</p>
<pre><code class="lang-typescript"><span class="hljs-comment">//theme-mapping.ts</span>

<span class="hljs-keyword">import</span> { ThemeName } <span class="hljs-keyword">from</span> <span class="hljs-string">'lib/context/ThemeContext'</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> getTheme = (siteName: <span class="hljs-built_in">string</span>): <span class="hljs-function"><span class="hljs-params">ThemeName</span> =&gt;</span> {
  <span class="hljs-comment">// This object should be configured manually for theming</span>
  <span class="hljs-keyword">const</span> themesAssociatedToSites: Record&lt;ThemeName, <span class="hljs-built_in">Array</span>&lt;<span class="hljs-built_in">string</span>&gt;&gt; = <span class="hljs-built_in">JSON</span>.parse(
    process.env.NEXT_PUBLIC_THEME_MAPPINGS || <span class="hljs-string">'{}'</span>
  );

  <span class="hljs-keyword">const</span> _themes = <span class="hljs-built_in">Object</span>.keys(themesAssociatedToSites) <span class="hljs-keyword">as</span> unknown <span class="hljs-keyword">as</span> ThemeName;
  <span class="hljs-keyword">let</span> currentTheme = <span class="hljs-built_in">Object</span>.keys(themesAssociatedToSites)[<span class="hljs-number">0</span>] <span class="hljs-keyword">as</span> ThemeName;

  <span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> i = <span class="hljs-number">0</span>; i &lt; _themes.length; i++) {
    <span class="hljs-keyword">if</span> (themesAssociatedToSites[_themes[i] <span class="hljs-keyword">as</span> ThemeName].includes(siteName))
      <span class="hljs-keyword">return</span> (currentTheme = _themes[i] <span class="hljs-keyword">as</span> ThemeName);
  }

  <span class="hljs-keyword">return</span> currentTheme;
};
</code></pre>
<p>Refer <code>/pages/_app.tsx</code> to understand how the above function is being used to detect the current theme.</p>
<h3 id="heading-configure-themes">Configure themes</h3>
<p>It's time to set up Tailwind configurations for multiple themes. In this example, we'll configure our app with <code>primary</code> and <code>secondary</code> themes. To do this, install the <a target="_blank" href="https://github.com/RyanClementsHax/tailwindcss-themer#readmehttps://github.com/RyanClementsHax/tailwindcss-themer#readme">tailwindcss-themer</a> plugin for multi-theming.</p>
<div data-node-type="callout">
<div data-node-type="callout-emoji">ℹ</div>
<div data-node-type="callout-text">The scope of this article is how to configure multi-theme using tailwind. We won’t be looking into how tailwind configuration works. You can find detailed instructions about tailwind configuration at <a target="_blank" href="https://tailwindcss.com/docs/configuration">Configuration - Tailwind CSS</a>.</div>
</div>

<p>There are a couple of basic steps to follow beforehand.</p>
<ol>
<li><p>Setup base configuration file</p>
</li>
<li><p>Setup theme configuration files</p>
</li>
<li><p>Export themes</p>
</li>
<li><p>Configure tailwind</p>
</li>
</ol>
<p>Now, create a folder named <code>theme</code> in the <code>src</code> directory. We will place theme configuration files in this folder, which includes the following files.</p>
<ul>
<li><p>index.js</p>
</li>
<li><p>tailwind.base.js (base-configuration-file)</p>
</li>
<li><p>tailwind.primary.js (theme-configuration-file)</p>
</li>
<li><p>tailwind.secondary.js (theme-configuration-file)</p>
</li>
</ul>
<h4 id="heading-setup-base-configuration-file">Setup base configuration file</h4>
<p>This configuration file contains base theme configurations that are common for all themes, such as spacing, breakpoints, etc.</p>
<pre><code class="lang-javascript"><span class="hljs-comment">//sample of tailwind.base.js</span>

<span class="hljs-built_in">module</span>.exports = {
  <span class="hljs-attr">extend</span>: {
    <span class="hljs-attr">name</span>: <span class="hljs-string">'base'</span>,
    <span class="hljs-attr">screens</span>: {
      <span class="hljs-attr">lg</span>: <span class="hljs-string">'1200px'</span>,
      <span class="hljs-attr">ml</span>: <span class="hljs-string">'960px'</span>,
      <span class="hljs-attr">md</span>: <span class="hljs-string">'720px'</span>,
      <span class="hljs-attr">sm</span>: <span class="hljs-string">'460px'</span>,
      <span class="hljs-attr">xs</span>: <span class="hljs-string">'320px'</span>,
    },
    <span class="hljs-attr">spacing</span>: {
      <span class="hljs-number">0</span>: <span class="hljs-string">'0'</span>,
      <span class="hljs-number">1</span>: <span class="hljs-string">'4px'</span>,
      <span class="hljs-number">2</span>: <span class="hljs-string">'8px'</span>,
      <span class="hljs-number">3</span>: <span class="hljs-string">'16px'</span>,
      <span class="hljs-number">4</span>: <span class="hljs-string">'24px'</span>,
      <span class="hljs-number">5</span>: <span class="hljs-string">'32px'</span>,
      <span class="hljs-number">6</span>: <span class="hljs-string">'64px'</span>,
      <span class="hljs-number">7</span>: <span class="hljs-string">'128px'</span>,
      <span class="hljs-number">8</span>: <span class="hljs-string">'256px'</span>,
    },
  }
}
</code></pre>
<h4 id="heading-setup-theme-configuration-files">Setup theme configuration files</h4>
<p>This configuration files contains theme specific configurations such as typography, colors, etc.</p>
<p>If you want to have a look at the files you can find theme in <code>src/theme</code> folder.</p>
<pre><code class="lang-javascript"><span class="hljs-comment">//tailwind.primary.js</span>

<span class="hljs-built_in">module</span>.exports = {
  <span class="hljs-attr">name</span>: <span class="hljs-string">'primary'</span>,
  <span class="hljs-attr">extend</span>: {
    <span class="hljs-attr">fontSize</span>: {
      <span class="hljs-comment">// Desktop font sizes</span>
      <span class="hljs-attr">xxl</span>: [<span class="hljs-string">'7.5rem'</span>, <span class="hljs-string">'100%'</span>], <span class="hljs-comment">//120px 120px</span>
      <span class="hljs-attr">xl</span>: [<span class="hljs-string">'3.5rem'</span>, <span class="hljs-string">'100%'</span>], <span class="hljs-comment">//56px 56px</span>
      <span class="hljs-attr">l</span>: [<span class="hljs-string">'3rem'</span>, <span class="hljs-string">'125%'</span>], <span class="hljs-comment">//48px 60px</span>
      <span class="hljs-attr">m</span>: [<span class="hljs-string">'2.25rem'</span>, <span class="hljs-string">'125%'</span>], <span class="hljs-comment">//36px 45px</span>
      <span class="hljs-attr">s</span>: [<span class="hljs-string">'1.5rem'</span>, <span class="hljs-string">'124%'</span>], <span class="hljs-comment">//24px 30px</span>
      <span class="hljs-attr">xs</span>: [<span class="hljs-string">'1.125rem'</span>, <span class="hljs-string">'100%'</span>], <span class="hljs-comment">//18px 18px</span>
      <span class="hljs-attr">xxs</span>: [<span class="hljs-string">'0.875rem'</span>, <span class="hljs-string">'120%'</span>], <span class="hljs-comment">//14px 16.8px</span>
      <span class="hljs-attr">body</span>: [<span class="hljs-string">'0.875rem'</span>, <span class="hljs-string">'157%'</span>], <span class="hljs-comment">//14px 22px</span>
      <span class="hljs-attr">button</span>: [<span class="hljs-string">'1rem'</span>, <span class="hljs-string">'1.125rem'</span>], <span class="hljs-comment">//16px 18px</span>
      <span class="hljs-string">'text-link'</span>: [<span class="hljs-string">'1rem'</span>, <span class="hljs-string">'1.125rem'</span>], <span class="hljs-comment">//16px 18px</span>
      <span class="hljs-attr">caption</span>: [<span class="hljs-string">'1rem'</span>, <span class="hljs-string">'0.875rem'</span>], <span class="hljs-comment">//16px 14px</span>
      <span class="hljs-attr">small</span>: [<span class="hljs-string">'0.75rem'</span>, <span class="hljs-string">'130%'</span>], <span class="hljs-comment">//12px 15.6px</span>
      <span class="hljs-attr">legal</span>: [<span class="hljs-string">'0.75rem'</span>, <span class="hljs-string">'130%'</span>], <span class="hljs-comment">//12px 15.6px</span>
      <span class="hljs-attr">base</span>: [<span class="hljs-string">'1rem'</span>, <span class="hljs-string">'1.125rem'</span>], <span class="hljs-comment">//16px 18px</span>
    },
    <span class="hljs-attr">colors</span>: {
      <span class="hljs-string">'light-gray'</span>: <span class="hljs-string">'#F8F6F4'</span>,
      <span class="hljs-string">'dark-gray'</span>: <span class="hljs-string">'#686869'</span>,
      <span class="hljs-attr">gray</span>: <span class="hljs-string">'#C4BFB6'</span>,
      <span class="hljs-attr">primary</span>: <span class="hljs-string">'red'</span>,
      <span class="hljs-attr">darkprimary</span>: <span class="hljs-string">'orange'</span>,
      <span class="hljs-attr">secondary</span>: <span class="hljs-string">'#000000'</span>,
      <span class="hljs-attr">white</span>: <span class="hljs-string">'#FFFFFF'</span>,
      <span class="hljs-attr">black</span>: <span class="hljs-string">'#000000'</span>,
      <span class="hljs-attr">transparent</span>: <span class="hljs-string">'transparent'</span>,
    },
    <span class="hljs-attr">fontWeight</span>: {
      <span class="hljs-attr">demi</span>: <span class="hljs-string">'500'</span>,
      <span class="hljs-attr">heavy</span>: <span class="hljs-string">'600'</span>,
      <span class="hljs-attr">bold</span>: <span class="hljs-string">'700'</span>,
      <span class="hljs-attr">medium</span>: <span class="hljs-string">'450'</span>,
      <span class="hljs-attr">regular</span>: <span class="hljs-string">'400'</span>,
      <span class="hljs-attr">light</span>: <span class="hljs-string">'300'</span>,
      <span class="hljs-attr">extralight</span>: <span class="hljs-string">'200'</span>,
    },
  },
};
</code></pre>
<pre><code class="lang-javascript"><span class="hljs-comment">//tailwind.secondary.js</span>

<span class="hljs-built_in">module</span>.exports = {
  <span class="hljs-attr">name</span>: <span class="hljs-string">'secondary'</span>,
  <span class="hljs-attr">extend</span>: {
    <span class="hljs-attr">fontSize</span>: {
      <span class="hljs-attr">xxl</span>: [<span class="hljs-string">'3.5rem'</span>, <span class="hljs-string">'114%'</span>], <span class="hljs-comment">//56px 63.84px</span>
      <span class="hljs-attr">xl</span>: [<span class="hljs-string">'3.5rem'</span>, <span class="hljs-string">'114%'</span>], <span class="hljs-comment">//56px 63.84px</span>
      <span class="hljs-attr">l</span>: [<span class="hljs-string">'2rem'</span>, <span class="hljs-string">'125%'</span>], <span class="hljs-comment">//32px 40px</span>
      <span class="hljs-attr">m</span>: [<span class="hljs-string">'1.5rem'</span>, <span class="hljs-string">'2rem'</span>], <span class="hljs-comment">//24px 32px</span>
      <span class="hljs-attr">s</span>: [<span class="hljs-string">'1.25rem'</span>, <span class="hljs-string">'1.75rem'</span>], <span class="hljs-comment">//20px 28px</span>
      <span class="hljs-attr">xs</span>: [<span class="hljs-string">'1rem'</span>, <span class="hljs-string">'1.25rem'</span>], <span class="hljs-comment">//16px 20px</span>
      <span class="hljs-attr">xxs</span>: [<span class="hljs-string">'0.75rem'</span>, <span class="hljs-string">'1rem'</span>], <span class="hljs-comment">//12px 16px</span>
      <span class="hljs-attr">body</span>: [<span class="hljs-string">'0.875rem'</span>, <span class="hljs-string">'157%'</span>], <span class="hljs-comment">//14px 21.98px</span>
      <span class="hljs-string">'large-body'</span>: [<span class="hljs-string">'1.125rem'</span>, <span class="hljs-string">'133%'</span>], <span class="hljs-comment">//18px 23.94px</span>
      <span class="hljs-attr">button</span>: [<span class="hljs-string">'0.875rem'</span>, <span class="hljs-string">'120%'</span>], <span class="hljs-comment">//14px 16.8px</span>
      <span class="hljs-string">'text-link'</span>: [<span class="hljs-string">'0.875rem'</span>, <span class="hljs-string">'0.875rem'</span>], <span class="hljs-comment">//14px 14px</span>
      <span class="hljs-attr">small</span>: [<span class="hljs-string">'0.75rem'</span>, <span class="hljs-string">'130%'</span>], <span class="hljs-comment">//12px 15.6px</span>
      <span class="hljs-attr">legal</span>: [<span class="hljs-string">'0.625rem'</span>, <span class="hljs-string">'130%'</span>], <span class="hljs-comment">//10px 13px</span>
      <span class="hljs-attr">base</span>: [<span class="hljs-string">'1rem'</span>, <span class="hljs-string">'1.125rem'</span>], <span class="hljs-comment">//16px 18px</span>
    },
    <span class="hljs-attr">colors</span>: {
      <span class="hljs-string">'light-gray'</span>: <span class="hljs-string">'#F9F9F9'</span>,
      <span class="hljs-string">'dark-gray'</span>: <span class="hljs-string">'#54585A'</span>,
      <span class="hljs-attr">gray</span>: <span class="hljs-string">'#D2D1D0'</span>,
      <span class="hljs-attr">primary</span>: <span class="hljs-string">'blue'</span>,
      <span class="hljs-attr">darkprimary</span>: <span class="hljs-string">'yellow'</span>,
      <span class="hljs-attr">secondary</span>: <span class="hljs-string">'#000000'</span>,
      <span class="hljs-attr">white</span>: <span class="hljs-string">'#FFFFFF'</span>,
      <span class="hljs-attr">black</span>: <span class="hljs-string">'#000000'</span>,
      <span class="hljs-attr">transparent</span>: <span class="hljs-string">'transparent'</span>,
      <span class="hljs-string">'light-black'</span>: <span class="hljs-string">'#454545'</span>,
    },
    <span class="hljs-attr">fontWeight</span>: {
      <span class="hljs-attr">bold</span>: <span class="hljs-string">'700'</span>,
      <span class="hljs-attr">heavy</span>: <span class="hljs-string">'600'</span>,
      <span class="hljs-string">'semi-bold'</span>: <span class="hljs-string">'600'</span>,
      <span class="hljs-attr">medium</span>: <span class="hljs-string">'500'</span>,
      <span class="hljs-attr">regular</span>: <span class="hljs-string">'400'</span>,
      <span class="hljs-string">'extra-light'</span>: <span class="hljs-string">'300'</span>,
    },
  },
};
</code></pre>
<div data-node-type="callout">
<div data-node-type="callout-emoji">⚠</div>
<div data-node-type="callout-text">Pay close attention while giving the theme name in configuration files because it’ll be considered while applying themes.</div>
</div>

<h4 id="heading-export-themes">Export themes</h4>
<p>Now that configuration files are all set up, Export them to use it. Create a <code>index.js</code> file that exports the themes. You can find this file in the same folder as other theme configuration files.</p>
<pre><code class="lang-javascript"><span class="hljs-comment">//index.js</span>
<span class="hljs-keyword">const</span> base = <span class="hljs-built_in">require</span>(<span class="hljs-string">'./tailwind.base'</span>);
<span class="hljs-keyword">const</span> primary = <span class="hljs-built_in">require</span>(<span class="hljs-string">'./tailwind.primary'</span>);
<span class="hljs-keyword">const</span> secondary = <span class="hljs-built_in">require</span>(<span class="hljs-string">'./tailwind.secondary'</span>);

<span class="hljs-built_in">module</span>.exports = {
  <span class="hljs-attr">base</span>: base,
  <span class="hljs-attr">themes</span>: [primary, secondary],
};
</code></pre>
<h4 id="heading-configure-tailwind">Configure tailwind</h4>
<p>In the previous step, we’ve exported the multiple themes that can be configured in Tailwind. It is time to configure the <code>tailwind.config.js</code> to apply themes in Tailwind.</p>
<p>First of all, set the base configuration file to setup the base theme object in <code>theme</code> key.</p>
<p>Now, Leverage the <a target="_blank" href="https://github.com/RyanClementsHax/tailwindcss-themer#readmehttps://github.com/RyanClementsHax/tailwindcss-themer#readme">tailwindcss-themer</a> plugin. This plugin expects an object with two keys.</p>
<ol>
<li><p><code>defaultTheme</code> : Provide default theme as a fallback.</p>
</li>
<li><p><code>themes</code> : It expects an array of themes that are configured in previous steps.</p>
</li>
</ol>
<p>Please refer to the code snippet below to understand it.</p>
<pre><code class="lang-javascript"><span class="hljs-comment">//tailwind.config.js</span>
<span class="hljs-keyword">const</span> app = <span class="hljs-built_in">require</span>(<span class="hljs-string">'./src/theme'</span>);

<span class="hljs-built_in">module</span>.exports = {
  <span class="hljs-attr">content</span>: [<span class="hljs-string">'./src/**/*.{js,ts,jsx,tsx}'</span>],
  <span class="hljs-attr">plugins</span>: [
    <span class="hljs-built_in">require</span>(<span class="hljs-string">'tailwindcss-themer'</span>)({
      <span class="hljs-attr">defaultTheme</span>: {
        <span class="hljs-attr">extend</span>: app.themes[<span class="hljs-number">0</span>], <span class="hljs-comment">//Provide default theme as a fallback</span>
      },
      <span class="hljs-attr">themes</span>: app.themes, <span class="hljs-comment">//Provide array of themes which are configured in previous steps.</span>
    }),
  ],
  <span class="hljs-attr">theme</span>: app.base, <span class="hljs-comment">//Provide base theme</span>
};
</code></pre>
<p>By following the above steps, multiple themes are successfully configured.</p>
<p>Now that we've successfully configured the multi-theming, Please refer <a target="_blank" href="https://saadpatel.hashnode.dev/easily-set-up-multi-theming-in-sitecore-jss-using-nextjs-and-tailwind-css-part-2">How to leverage multi-theming</a> as a next step to leverage multi-theming in the app.</p>
]]></content:encoded></item></channel></rss>