In this article we will uncover the step-by-step process of integrating Tailwind CSS into your Sitecore Next.js application, and witness how this dynamic duo empowers developers to craft stunning user interfaces without compromising on loading speeds.
Learn from real-world examples, best practices, and unleash the true potential of your web development endeavors. Join us on this journey where design meets efficiency, and aesthetics merge with functionality.
Learn from real-world examples, best practices, and unleash the true potential of your web development endeavors. Join us on this journey where design meets efficiency, and aesthetics merge with functionality.
In the world of web development, finding the perfect balance between design flexibility and performance optimization is a perpetual challenge. Enter the dynamic pairing of Tailwind CSS and Sitecore Next.js – a match made in developer heaven. In this guide, we'll walk you through the process of integrating Tailwind CSS into your Sitecore Next.js application, showcasing how this combination can revolutionize your web development workflow.
Tailwind CSS is a utility-first CSS framework that offers a rapid and structured approach to designing user interfaces. On the other hand, Sitecore Next.js SDK is a powerful offering from true Headless CMS Sitecore to build the future ready Jamstack application using Next.js modern client-side scripting framework. By combining these two technologies, you're set to experience the best of both worlds: Tailwind's design prowess and Next.js's performance benefits.
Instead of just giving you styling systems or component libraries with pre-defined styles like prebuild component designs the JavaScript based CSS solutions do, Tailwind CSS gives you access to a variety of useful, neutral CSS classes. Your components can use these classes to create your user experience, and you have the option to build on them using configuration files.
Instead of just giving you styling systems or component libraries with pre-defined styles like prebuild component designs the JavaScript based CSS solutions do, Tailwind CSS gives you access to a variety of useful, neutral CSS classes. Your components can use these classes to create your user experience, and you have the option to build on them using configuration files.
A utility-first approach to styling is used in Tailwind CSS. It offers a huge selection of tiny, specialised utility classes that you can immediately apply to your HTML components.
By combining these classes, it is simple to create sophisticated UI components because each utility class represents a particular CSS value or set of properties.
For instance, to change the colour of a button without having to define a custom CSS class, you can just use the text-red-400 utility class.
Tailwind CSS's utility classes are created with extreme flexibility and customizability in mind. By utilizing the logical naming conventions offered by Tailwind, you can quickly change parameters such as margin, padding, font size, colors and more.
By combining these classes, it is simple to create sophisticated UI components because each utility class represents a particular CSS value or set of properties.
For instance, to change the colour of a button without having to define a custom CSS class, you can just use the text-red-400 utility class.
Tailwind CSS's utility classes are created with extreme flexibility and customizability in mind. By utilizing the logical naming conventions offered by Tailwind, you can quickly change parameters such as margin, padding, font size, colors and more.
-
Setting Up the Project:
Begin by creating a new Sitecore Next.js project or using an existing one. Install the necessary dependencies, including Tailwind CSS and any other required packages.
You can follow the steps mentioned at Set Up the Sitecore Container in Configuring Sitecore Next.js Headless SXA Multisite App in a Sitecore Container article.
After all the setup/configuration steps, start the front-end application in connected mode with the command: jss start:connected to validate that Next.js app working fine or not. -
Configuring Tailwind CSS:
Dive into Tailwind's configuration to customize the design system according to your project's needs. Modify color schemes, typography settings, and more to align with your brand identity.
To build tailwind.config.js and postcss.config.js, run the init command after installing tailwindcss and adding its peer dependencies via npm.
npm install -D tailwindcss postcss autoprefixer npx tailwindcss init -p
-
Set up the template routes:
The default tailwind.config.js file is:
/** @type {import('tailwindcss').Config} */ module.exports = { content: [], theme: { extend: {}, }, plugins: [], }
Now, place the locations to the files that will utilize Tailwind CSS class names within tailwind.config.js
/** @type {import('tailwindcss').Config} */ module.exports = { content: [ './app/**/*.{js,ts,jsx,tsx,mdx}', // Note the addition of the `app` directory. './pages/**/*.{js,ts,jsx,tsx,mdx}', './components/**/*.{js,ts,jsx,tsx,mdx}', // Or if using `src` directory: './src/**/*.{js,ts,jsx,tsx,mdx}', ], theme: { extend: {}, }, plugins: [], }
You do not need to modify postcss.config.js. -
Integrate Tailwind styles into your Sitecore Next.js app:
In your application, include the Tailwind CSS directives into your application’s Global Stylesheet which generally present at app/globals.css or src\assets\globals.css and Tailwind will utilize this file to inject its created styles.
If Global stylesheet file does not present then create at src\assets\globals.css and include following Tailwind CSS directives:
@tailwind base; @tailwind components; @tailwind utilities;
Our application will load without styles if we verify it right now. -
Load Global Stylesheet into your Sitecore Next.js app:
In the previous step you have created the css file but not included in your application so that it will be available to all routes. For this go to your src\pages\_app.tsx file and import css file updated in previous step
import type { AppProps } from 'next/app'; import { I18nProvider } from 'next-localization'; import { SitecorePageProps } from 'lib/page-props'; import 'assets/main.scss'; import 'assets/globals.css'; function App({ Component, pageProps }: AppProps<SitecorePageProps>): JSX.Element { const { dictionary, ...rest } = pageProps; return ( // Use the next-localization (w/ rosetta) library to provide our translation dictionary to the app. // Note Next.js does not (currently) provide anything for translation, only i18n routing. // If your app is not multilingual, next-localization and references to it can be removed. <I18nProvider lngDict={dictionary} locale={pageProps.locale}> <Component {...rest} /> </I18nProvider> ); } export default App;
You can utilise Tailwind's utility classes in your application after installing Tailwind CSS and setting the global styles. For this test following HTML into your existing component:
<h1 className="text-3xl font-bold underline">Hello, <span class="text-red-400">Sitecore Next.js</span> and <span class="text-sky-500 dark:text-sky-400">Tailwind CSS</span> !</h1>
And the output would be:
-
Creating Component with Tailwind:
Learn how to harness Tailwind's utility classes to swiftly build UI components. From buttons to grids, discover how easy it is to style your application using concise class names.
Lets create the responsive Global Navbar in Next.js with tailwindcss
-
The JSON response from Sitecore CMS for Navigation bar component is
{ "data": { "item": { "rendered": { "sitecore": { "context": { "pageEditing": false, "site": { "name": "MyProject" }, "pageState": "normal", "language": "en", "itemPath": "/" }, "route": { "name": "Home", "displayName": "Home", "fields": { "Title": { "value": "MyProject Site - Home" }, "Content": { "value": "" }, "NavigationTitle": { "value": "Home" }, "Page Design": { "id": "90e9ca30-b7e9-43d4-a826-98377b0e1ff2", "url": "/Presentation/Page-Designs/Home", "name": "Home", "displayName": "Home Page Design", "fields": { "PartialDesigns": { "value": "{xxxx}|{xx}" } } } }, "databaseName": "web", "deviceId": "xxxxx", "itemId": "xxxxx", "itemLanguage": "en", "itemVersion": 1, "layoutId": "xxxx", "templateId": "xxx", "templateName": "Page", "placeholders": { "headless-header": [ { "uid": "5xx", "componentName": "PartialDesignDynamicPlaceholder", "dataSource": "", "params": { "sid": "{bf277516-0232-44d6-88ca-ebcc4e2d3cb0}", "ph": "headless-header", "sig": "sxa-homepage" }, "placeholders": { "sxa-homepage": [ { "uid": "8380d3f5-c272-4f7f-b204-01033f6cb9a7", "componentName": "NavigationList", "dataSource": "{xxxxxx}", "fields": { "NavList": [ { "id": "xxxx", "url": "/Data/Navigations/NavigationLists/Mainsite/aboutus", "name": "aboutus", "displayName": "About Us", "fields": { "LinkText": { "value": "About Us" }, "Link": { "value": { "href": "/aboutus", "text": "About Us", "linktype": "external", "url": "/aboutus", "anchor": "", "target": "" } } } }, { "id": "xxxx", "url": "/Data/Navigations/NavigationLists/Mainsite/products", "name": "products", "displayName": "Products", "fields": { "LinkText": { "value": "Products" }, "Link": { "value": { "href": "/products", "text": "Products", "linktype": "external", "url": "/products", "anchor": "", "target": "" } } } }, { "id": "xxxx", "url": "/Data/Navigations/NavigationLists/Mainsite/privacypolicy", "name": "privacypolicy", "displayName": "Privacy Policy", "fields": { "LinkText": { "value": "Privacy Policy" }, "Link": { "value": { "href": "/privacypolicy", "text": "Privacy Policy", "linktype": "external", "url": "/privacypolicy", "anchor": "", "target": "" } } } }, { "id": "xxxx", "url": "/Data/Navigations/NavigationLists/Mainsite/contactus", "name": "contactus", "displayName": "Contact Us", "fields": { "LinkText": { "value": "Contact Us" }, "Link": { "value": { "href": "/contactus", "text": "Contact Us", "linktype": "external", "url": "/contactus", "anchor": "", "target": "" } } } } ] } } ] } } ], "headless-main": [], "headless-footer": [] } } } } } } }
Here the values of SITECORE_MODULE_REGISTRY and SPE_VERSION defined in the environment (.env) file as
-
Now, go to the src\components\Navigation\ and create the file NavBar.tsx and below code:
import Link from 'next/link'; import { useState } from 'react'; import { Field } from '@sitecore-jss/sitecore-jss-nextjs'; export type NavItemFields = { LinkText: { value: string; }; Link: { value: { href: string; text: string; linktype: string; url: string; anchor: string; target: string; }; }; }; type NavList = { name: Field<string>; displayName: Field<string>; fields:NavItemFields ; }; type NavigationList = { NavigationBarList: NavList[]; }; function NavBar(props: NavigationList) { const [navbar, setNavbar] = useState(false); const navListItems = props.NavigationBarList && props.NavigationBarList.map((navItem, index) => ( <li key={index} className="pb-6 text-xl text-white py-2 md:px-6 text-center border-b-2 md:border-b-0 hover:bg-purple-900 border-purple-900 md:hover:text-purple-600 md:hover:bg-transparent"> <Link href={navItem.fields.Link.value.href} onClick={() => setNavbar(!navbar)}> {navItem.fields.Link.value.text} </Link> </li> )); return ( <div> <nav className="w-full bg-black fixed top-0 left-0 right-0 z-10"> <div className="justify-between px-4 mx-auto lg:max-w-7xl md:items-center md:flex md:px-8"> <div> <div className="flex items-center justify-between py-3 md:py-5 md:block"> {/* LOGO */} <Link href="/"> <h2 className="text-2xl text-cyan-600 font-bold ">LOGO</h2> </Link> {/* HAMBURGER BUTTON FOR MOBILE */} <div className="md:hidden"> <button className="p-2 text-gray-700 rounded-md outline-none focus:border-gray-400 focus:border" onClick={() => setNavbar(!navbar)} > {navbar ? ( <svg xmlns="http://www.w3.org/2000/svg" className="w-6 h-6 text-white" viewBox="0 0 20 20" fill="currentColor" > <path fillRule="evenodd" d="M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z" clipRule="evenodd" /> </svg> ) : ( <svg xmlns="http://www.w3.org/2000/svg" className="w-6 h-6 text-white" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2} > <path strokeLinecap="round" strokeLinejoin="round" d="M4 6h16M4 12h16M4 18h16" /> </svg> )} </button> </div> </div> </div> <div> <div className={`flex-1 justify-self-center pb-3 mt-8 md:block md:pb-0 md:mt-0 ${ navbar ? 'p-12 md:p-0 block' : 'hidden' }`} > <ul className="h-screen md:h-auto items-center justify-center md:flex "> {navListItems} </ul> </div> </div> </div> </nav> </div> ); } export default NavBar;
In the above code, we are receiving the properties from main component and using loop to render the list of the Link items.
-
Go the parent component called NavigationList (src\components\Navigation\NavigationList\NavigationList.tsx) which received the JSON data from Sitecore CMS and import the NavBar component like this:
import Link from 'next/link'; import { useState } from 'react'; import { Field } from '@sitecore-jss/sitecore-jss-nextjs'; export type NavItemFields = { LinkText: { value: string; }; Link: { value: { href: string; text: string; linktype: string; url: string; anchor: string; target: string; }; }; }; type NavList = { name: Field<string>; displayName: Field<string>; fields:NavItemFields ; }; type NavigationList = { NavigationList: NavList[]; }; function NavBar(props: NavigationList) { const [navbar, setNavbar] = useState(false); const navListItems = props.NavigationList && props.NavigationList.map((navItem, index) => ( <li key={index} className="pb-6 text-xl text-white py-2 md:px-6 text-center border-b-2 md:border-b-0 hover:bg-purple-900 border-purple-900 md:hover:text-purple-600 md:hover:bg-transparent"> <Link href={navItem.fields.Link.value.href} onClick={() => setNavbar(!navbar)}> {navItem.fields.Link.value.text} </Link> </li> )); return ( <div> <nav className="w-full bg-black fixed top-0 left-0 right-0 z-10"> <div className="justify-between px-4 mx-auto lg:max-w-7xl md:items-center md:flex md:px-8"> <div> <div className="flex items-center justify-between py-3 md:py-5 md:block"> {/* LOGO */} <Link href="/"> <h2 className="text-2xl text-cyan-600 font-bold ">LOGO</h2> </Link> {/* HAMBURGER BUTTON FOR MOBILE */} <div className="md:hidden"> <button className="p-2 text-gray-700 rounded-md outline-none focus:border-gray-400 focus:border" onClick={() => setNavbar(!navbar)} > {navbar ? ( <svg xmlns="http://www.w3.org/2000/svg" className="w-6 h-6 text-white" viewBox="0 0 20 20" fill="currentColor" > <path fillRule="evenodd" d="M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z" clipRule="evenodd" /> </svg> ) : ( <svg xmlns="http://www.w3.org/2000/svg" className="w-6 h-6 text-white" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2} > <path strokeLinecap="round" strokeLinejoin="round" d="M4 6h16M4 12h16M4 18h16" /> </svg> )} </button> </div> </div> </div> <div> <div className={`flex-1 justify-self-center pb-3 mt-8 md:block md:pb-0 md:mt-0 ${ navbar ? 'p-12 md:p-0 block' : 'hidden' }`} > <ul className="h-screen md:h-auto items-center justify-center md:flex "> {navListItems} </ul> </div> </div> </div> </nav> </div> ); } export default NavBar;
In the above code, we are receiving the properties from main component and using loop to render the list of the Link items.
-
The above component will render the responsive Navigation bar into the Sitecore Next.Js page:
-
The JSON response from Sitecore CMS for Navigation bar component is
-
Optimizing for Production:
Explore techniques to optimize the production build of your Sitecore Next.js app. Minify and purge unused CSS classes to ensure a streamlined and efficient final output.
-
Responsive Design with Ease:
Embrace Tailwind's responsive design capabilities by crafting layouts that adapt seamlessly across various screen sizes. Say goodbye to complex media queries and embrace intuitive responsive classes.
You can learn more at:
-
Animations and Transitions:
You can elevate user experience by adding subtle animations and transitions using Tailwind CSS. Discover how to animate elements on hover or during page transitions without compromising on performance.
For example, if you add below HTML into your component
<h3 class="animate-ping m-auto bg-blue text-center text-red-400"> Article From Amit Kumar </h3>
And effect would be like this:
You can see that how easy to implement animations in your website.
You can learn more at: -
Theming and Dark Mode:
You can uncover the potential of theming and dark mode implementation with Tailwind CSS. Allow users to switch between light and dark themes effortlessly, enhancing accessibility and user preference.
By using Tailwind CSS with Sitecore Next.js you can enhance your application's performance. Thanks to optimized production builds and efficient CSS handling, your users will enjoy faster loading times and smoother interactions.
The integration of Tailwind CSS into your Sitecore Next.js application opens up a realm of possibilities for designing and building exceptional web interfaces. By leveraging Tailwind's utility classes and Sitecore Next.js's performance advantages, you can create visually stunning, lightning-fast web applications that truly stand out in today's competitive digital landscape. So, why wait? Start your journey to a more efficient and stylish web development workflow today!