Uniform how-to/Build a Component Library with Tailwind UI and Nuxt 3
12 min read
Build a Component Library with Tailwind UI and Nuxt 3
Components in apps are building blocks that perform related functions that are pluggable and reusable. Popular frameworks have all adopted the component way as an effective approach.
TailwindUI is a collection of well-designed components and templates ideal for building websites and apps.
This tutorial, whose source code is on GitHub, describes how to create a component library with TailwindUI and Uniform in Nuxt 3 in the StackBlitz IDE, which you can leverage with this codeline:
<iframe src="https://stackblitz.com/edit/github-anehxu?embed=1&file=app.vue"></iframe>Click to copy
Understanding the prerequisites
To fully grasp the concepts in this tutorial, you must have—
- A basic understanding of Vue and Nuxt
- A fundamental knowledge of Tailwind CSS
- A Uniform account, which you can create for free.
Uniform offers digital experience composition (DXC) features with which you can create, deliver, and manage building blocks for apps. Instead of making multiple API requests, you can employ Jamstack technologies, such as headless content-management systems, commerce APIs, and CDNs, and deliver digital experiences as a single source of truth.
Getting started
First, create a Nuxt 3 starter project by typing this command in a directory of your choice:
1npx nuxi init uniform-nuxt && cd uniform-nux
In the project directory, install the project dependencies:
npm i Click to copy
Adding TailwindCSS support
Next, install and configure TailwindCSS, a prerequisite for TailwindUI, in your app. Follow these steps:
- Install Tailwind CSS and its dependencies. TypeThe above command line also creates a
1npm install -D tailwindcss postcss@latest autoprefixer@latest @nuxt/postcss8 2npx tailwindcss init
tailwind.config.jsClick to copy
file for configuring Tailwind CSS. - Add the paths to the template files to the
tailwind.config.jsClick to copy
file, like this:1 /** @type {import('tailwindcss').Config} */ 2module.exports = { 3 content: [ 4 './components/**/*.{js,vue,ts}', 5 './layouts/**/*.vue', 6 './pages/**/*.vue', 7 './**/*.vue', 8 './plugins/**/*.{js,ts}', 9 ], 10 theme: { 11 extend: {}, 12 }, 13 plugins: [], 14};
- Create an
assets/css/tailwind.cssClick to copy
file in the root directory and add Tailwind CSS directives:1@tailwind base; 2@tailwind components; 3@tailwind utilities;
- Add the Tailwind CSS dependencies and the newly created style to configure Nuxt 3 by updating the
nuxt.config.jsClick to copy
file with the code below:import { defineNuxtConfig } from 'nuxt';Click to copy
1// https://v3.nuxtjs.org/api/configuration/nuxt.config 2export default defineNuxtConfig({ 3 build: { 4 postcss: { 5 postcssOptions: { 6 plugins: { 7 tailwindcss: {}, 8 autoprefixer: {}, 9 }, 10 }, 11 }, 12 }, 13 css: ['~/assets/css/tailwind.css'] 14});
Adding TailwindUI
Now add Tailwind UI to your app:
- Install the required dependencies:
npm install @headlessui/vue @heroicons/vueClick to copy
- Update the
app.vue Click to copy
file with this code:1<!-- This example requires Tailwind CSS v2.0+ --> 2<template> 3 <div class="py-12 bg-white"> 4 <div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8"> 5 <div class="lg:text-center"> 6 <h2 class="text-base text-indigo-600 font-semibold tracking-wide uppercase">Transactions</h2> 7 <p class="mt-2 text-3xl leading-8 font-extrabold tracking-tight text-gray-900 sm:text-4xl">A better way to send money</p> 8 <p class="mt-4 max-w-2xl text-xl text-gray-500 lg:mx-auto">Lorem ipsum dolor sit amet consect adipisicing elit. Possimus magnam voluptatum cupiditate veritatis in accusamus quisquam.</p> 9 </div> 10 <div class="mt-10"> 11 <dl class="space-y-10 md:space-y-0 md:grid md:grid-cols-2 md:gap-x-8 md:gap-y-10"> 12 <div v-for="feature in features" :key="feature.name" class="relative"> 13 <dt> 14 <div class="absolute flex items-center justify-center h-12 w-12 rounded-md bg-indigo-500 text-white"> 15 <component :is="feature.icon" class="h-6 w-6" aria-hidden="true" /> 16 </div> 17 <p class="ml-16 text-lg leading-6 font-medium text-gray-900">{{ feature.name }}</p> 18 </dt> 19 <dd class="mt-2 ml-16 text-base text-gray-500"> 20 {{ feature.description }} 21 </dd> 22 </div> 23 </dl> 24 </div> 25 </div> 26 </div> 27</template> 28<script setup> 29import { AnnotationIcon, GlobeAltIcon, LightningBoltIcon, ScaleIcon } from '@heroicons/vue/outline' 30const features = [ 31 { 32 name: 'Competitive exchange rates', 33 description: 34 'Lorem ipsum, dolor sit amet consectetur adipisicing elit. Maiores impedit perferendis suscipit eaque, iste dolor cupiditate blanditiis ratione.', 35 icon: GlobeAltIcon, 36 }, 37 { 38 name: 'No hidden fees', 39 description: 40 'Lorem ipsum, dolor sit amet consectetur adipisicing elit. Maiores impedit perferendis suscipit eaque, iste dolor cupiditate blanditiis ratione.', 41 icon: ScaleIcon, 42 }, 43 { 44 name: 'Transfers are instant', 45 description: 46 'Lorem ipsum, dolor sit amet consectetur adipisicing elit. Maiores impedit perferendis suscipit eaque, iste dolor cupiditate blanditiis ratione.', 47 icon: LightningBoltIcon, 48 }, 49 { 50 name: 'Mobile notifications', 51 description: 52 'Lorem ipsum, dolor sit amet consectetur adipisicing elit. Maiores impedit perferendis suscipit eaque, iste dolor cupiditate blanditiis ratione.', 53 icon: AnnotationIcon, 54 }, 55] 56</script
Note: Tailwind UI comes with free and paid templates. The template in this tutorial is a free marketing template.
- Finally, start a development server:
1npm run dev
Putting it all together on Uniform
Now create a component library on Uniform.
- Log in to your Uniform account and click Create New Project at the top. Type
marketing_featureClick to copy
under Give your project a name and click Continue. - Click the Security tab at the top, then API Keys, and then the + icon to create an API key. Input
marketing_featureClick to copy
as the API name, click Add to Project, select all the permissions, and click Set Permissions. Finally, click Create API Key.
A screen that contains your API Key and Project ID is then displayed.
Before closing the screen, create a
.envClick to copy
file in your app’s root directory and add this code snippet to the file:1NUXT_ENV_API_KEY=/REPLACE WITH API KEY/
2NUXT_ENV_PROJECT_ID=/REPLACE WITH PROJECT ID/
Click to copy
Understanding and setting up components and compositions on Uniform
Components in Uniform apps work similarly to those in Vue apps, i.e., you can break up an app into smaller, reusable building blocks with properties. A composition contains one or more components.
For this project, create a single
header_componentClick to copy
and four instances of body_componentClick to copy
.Follow these steps:
1. Click the Projects tab at the top and then the project. Afterwards, click the Canvas tab at the top, then Component Library, and the + icon.
Parameter Name | Help Text | Type | Required? |
---|---|---|---|
mini title | Mini title | Text | Yes |
main title | Main title | Text | Yes |
description | Description | Text | Yes |
2. Type
header_componentClick to copy
as the component name, add the properties of mini titleClick to copy
, main titleClick to copy
, and descriptionClick to copy
as shown above, and then click OK.3. Click Save and Close.
Similarly, create a
body_componentClick to copy
component with these properties:Parameter Name | Help Text | Type | Required? |
---|---|---|---|
title | Title | Text | Yes |
description | Description | Text | Yes |
Be sure to click Save and Close.
header_componentClick to copy
and body_componentClick to copy
now serve as the blueprints or building blocks for your marketing landing page. Create that page with the following steps:- Click the + icon, type
PageClick to copy
under Component Name, and select Composition Component. Afterwards, click Slots below and click the + icon to create a slot.Note: With slots, you can create component instances (a total of five in this tutorial), which can accept data dynamically. - Type
ItemsClick to copy
under Slot Name,0Click to copy
under Minimum,5Click to copy
under Maximum (the header section and the four body sections), and selectbody_componentClick to copy
andheader_componentClick to copy
under Allowed Components. Click OK. - Finally, click Save and Close.
You can now build your marketing landing page with the
PagesClick to copy
component. Do the following:- Click Compositions on the left and then the + icon to create a composition.
- Select
PageClick to copy
as the composition type, inputHomepageClick to copy
as the name, and click Create. - Type
itemsClick to copy
under Slug and click the + icon to add a component to map out a new component.Note: The slug you added will come in handy for composition searches. - Select
header_componentClick to copy
and add the corresponding text undermini titleClick to copy
,main titleClick to copy
, anddescriptionClick to copy
as hard-coded in your Nuxt 3 app. - Repeat the above steps to add the remaining
body_componentClick to copy
data and then click Save and Publish. - Navigate back to the Canvas tab and click Publish to make your composition available to third-party apps.
Integrating Uniform with Nuxt 3
To integrate Uniform with Nuxt 3:
- Install the required dependencies with this command:
npm install @uniformdev/canvas @uniformdev/context @uniformdev/canvas-vue @uniformdev/context-vue @uniformdev/uniform-nuxtClick to copy
- Configure and register Uniform as a module in your Nuxt 3 app by editing the
nuxt.config.tsClick to copy
file to read as follows:import { defineNuxtConfig } from 'nuxt';Click to copy
1// https://v3.nuxtjs.org/api/configuration/nuxt.config 2export default defineNuxtConfig({ 3 build: { 4 postcss: { 5 postcssOptions: { 6 plugins: { 7 tailwindcss: {}, 8 autoprefixer: {}, 9 }, 10 }, 11 }, 12 }, 13 css: ['~/assets/css/tailwind.css'], 14 //add below section 15 modules: ['@uniformdev/uniform-nuxt'], 16 uniform: { 17 projectId: process.env.NUXT_ENV_PROJECT_ID, 18 readOnlyApiKey: process.env.NUXT_ENV_API_KEY, 19 }, 20});
- Retrieve your data with an API call through the configured Uniform module by editing the
app.vueClick to copy
file to read like this:1<!-- This example requires Tailwind CSS v2.0+ --> 2<template> 3 <Composition v-if="composition" :data="composition"> 4 <div class="py-12 bg-white"> 5 <div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8"> 6 <div class="lg:text-center"> 7 <h2 8 class="text-base text-indigo-600 font-semibold tracking-wide uppercase" 9 >{{composition.slots.items[0].parameters.miniTitle.value}}</h2> 10 <p 11 class="mt-2 text-3xl leading-8 font-extrabold tracking-tight text-gray-900 sm:text-4xl" 12 >{{composition.slots.items[0].parameters.mainTitle.value}}</p> 13 <p 14 class="mt-4 max-w-2xl text-xl text-gray-500 lg:mx-auto" 15 >{{composition.slots.items[0].parameters.description.value}}</p> 16 </div> 17 <div class="mt-10"> 18 <dl class="space-y-10 md:space-y-0 md:grid md:grid-cols-2 md:gap-x-8 md:gap-y-10"> 19 <div 20 v-for="(feature, i) in composition.slots.items.slice(1)" 21 :key="feature.name" 22 class="relative" 23 > 24 <dt> 25 <div 26 class="absolute flex items-center justify-center h-12 w-12 rounded-md bg-indigo-500 text-white" 27 > 28 <component :is="iconArray[i]" class="h-6 w-6" aria-hidden="true" /> 29 </div> 30 <p 31 class="ml-16 text-lg leading-6 font-medium text-gray-900" 32 >{{ feature.parameters.title.value }}</p> 33 </dt> 34 <dd 35 class="mt-2 ml-16 text-base text-gray-500" 36 >{{ feature.parameters.description.value }}</dd> 37 </div> 38 </dl> 39 </div> 40 </div> 41 </div> 42 </Composition> 43</template> 44<script setup> 45import { 46 AnnotationIcon, 47 GlobeAltIcon, 48 LightningBoltIcon, 49 ScaleIcon 50} from "@heroicons/vue/outline"; 51const iconArray = [AnnotationIcon, GlobeAltIcon, LightningBoltIcon, ScaleIcon]; 52const { $useComposition } = useNuxtApp(); 53const { data: compositionData } = await $useComposition({ slug: "items" }); 54const composition = computed(() => compositionData.value.composition); 55</script>
The snippet above does the following:
- Creates an
iconArrayClick to copy
array to store the icons. - Retrieves data from Uniform with the
$useCompositionClick to copy
instance by passing on theitemsClick to copy
slug you configured on Uniform earlier. - Creates a
compositionClick to copy
variable to hold the composition retrieved from Uniform. - Performs a conditional check: If
compositionClick to copy
is not empty, dynamically update the UI with thecompositionClick to copy
component.
Now you can restart your development server. Type:
npm run devClick to copy
Configuring Live Previews
Uniform’s intuitive UI enables developers to preview changes in realtime and avoid context switching between the platform and the codebase. To set up live previews:
- Click the Settings tab followed by Canvas, and then input the development URL
http://localhost:3000/?preview=trueClick to copy
. Click Save.Note: For deployed apps, be sure to input the correct URL. For example, inputhttps://myapp.com/?preview=trueClick to copy
for the apphttps://myapp.comClick to copy
. - Navigate back to the Canvas tab and click Homepage composition. The Preview button is displayed on the top-right corner.To test the live-preview capability and see changes in real time, edit a component, save it, and click Preview.
Exploring other resources
You’ve now learned how to create a component library with TailwindUI and Uniform in Nuxt 3. Besides enhancing the digital experience and raisingapp performance with only a single API call, Uniform also shortens time tomarket by offering developers and nondevelopers a seamless and intuitive UI for content edits.
Here are a few helpful resources: