I have got a nextjs project where i'm using tailwind. On build I load in a default config, but then i also want to wait for an API response to get custom styles from an endpoint.
This is what I have got below however I feel like i'm going about this the wrong way, currently getting webpack errors:
Error: Cannot find module './services/getThemeStyles'
// ./tailwind.config.js
// Default styles
const theme = require('./lib/themes/default/tailwind/tailwind.config');
// Website custom styles
const custom = require('./services/getThemeStyles');
module.exports = {
...theme, // Do deep merge here of theme and custom
content: ['./lib/**/*.{js,ts,jsx,tsx}', './pages/**/*.{js,ts,jsx,tsx}', './components/**/*.{js,ts,jsx,tsx}'],
};
// ./services/getThemeStyles.ts
// Fake temp endpoint, this would hit an API when working.
const theme = require('/data/theme');
export default async function getThemeStyles(): Promise<any> {
return new Promise((resolve) => {
setTimeout(() => {
resolve(theme);
}, 1);
});
}
// ./data/theme.ts
const Theme = {
extend: {
colors: {
'banner-background': 'rgb(220,220,0)'
}
}
}
export default Theme;
Anyone done this before or can anyone help me out?
Changed my approach, made a node server so getting data is more realistic, so now my tailwind.config.js looks like this:
const fetch = require('node-fetch');
const merge = require('merge-deep');
module.exports = (async function() {
let theme = require('./lib/themes/default/tailwind/tailwind.config');
const response = await fetch('http://localhost:5000/data');
const data = await response.json();
return {
...merge(theme, data),
content: ['./lib/**/*.{js,ts,jsx,tsx}', './pages/**/*.{js,ts,jsx,tsx}', './components/**/*.{js,ts,jsx,tsx}'],
}
})();
However I can't put await infront of fetch due to not being in a async function, so the module is being exported before the request is returned.
Found a solution, in-case anyone else is trying to do this also!
Simply using a next plugin (might be possible without plugin) to download the file before build, then import this file within tailwind config.
Only issue is there is an infinite loop when trying to run next dev so only pull the file when building for production.
But for my use case this is okay.
// next.config.js
const WebpackBeforeBuildPlugin = require('before-build-webpack');
const fs = require('fs');
/** @type {import('next').NextConfig} */
const nextConfig = {
reactStrictMode: true,
webpack: (config, options) => {
if (process.env.NODE_ENV === 'development') {
return config;
}
// Important: return the modified config
config.plugins.push(new WebpackBeforeBuildPlugin(async function(stats, callback) {
const response = await fetch("http://localhost:5000/data");
const dt = await response.json();
fs.writeFileSync('./.tmp/custom.json', JSON.stringify(dt));
callback();
}))
return config;
},
};
module.exports = nextConfig;
// tailwind.config.js
const merge = require('merge-deep');
const theme = require('./lib/themes/default/tailwind/tailwind.config');
let custom = null;
// Try and merge any custom styles with the selected theme
try {
custom = require('./.tmp/custom.json');
} catch (e) {
custom = [];
}
module.exports = {
...merge(theme, custom),
content: ['./lib/**/*.{js,ts,jsx,tsx}', './pages/**/*.{js,ts,jsx,tsx}', './components/**/*.{js,ts,jsx,tsx}'],
};