Not sure to understand your question.
Here is what I use for postCSS
partials/style.html
<!-- Variables for purgecss -->
{{- $isProd := hugo.IsProduction -}}
{{ $options := dict "inlineImports" true }}
<!-- plugins + stylesheet -->
{{ $styles := slice }}
{{ range site.Params.plugins.css }}
{{ if findRE "^http" .link }}
<link crossorigin="anonymous" media="all" rel="stylesheet" href="{{ .link | relURL }}" {{.attributes | safeHTMLAttr}} >
{{ else }}
{{ $styles = $styles | append (resources.Get .link) }}
{{ end }}
{{ end }}
{{ $styles := $styles | append (resources.Get "scss/style.scss" | resources.ExecuteAsTemplate "style.scss" . | toCSS) }}
{{ $styles = $styles | resources.Concat "/css/style.css" }}
{{- partial "partials/css-process" (dict "context" . "css" $styles "options" $options "isprod" true ) }}
<!--
For processing CSS as assets
Parameters : (dict "context" . "css" $css "isprod" true "options" "")
-->
{{- define "partials/css-process" }}
{{- $css := .css }}
{{- $isProd := .isprod | default hugo.IsProduction }}
{{- $options := .options | default ""}}
{{- $media := .media | default "screen"}}
{{- $nopurge := .nopurge | default false }}
{{- if $isProd }}
{{- if and site.Params.purgecss (not $nopurge) }}
{{ `<!-- purgeCSS ON -->` | safeHTML }}
{{- $css = $css | resources.PostCSS $options}}
{{- $css = $css | minify | fingerprint "sha384" | resources.PostProcess }}
{{- else }}
{{ `<!-- purgeCSS Off -->` | safeHTML }}
{{- $css = $css | minify | fingerprint "sha384" | resources.PostProcess }}
{{- end }}
{{- else }}
{{- $css = $css | fingerprint "sha384" }}
{{- end }}
<link rel="preload" href="{{ $css.RelPermalink }}" as="style" media="{{ $media }}" {{ if $isProd }}integrity="{{ $css.Data.Integrity }}"{{ end }}>
<link href="{{ $css.RelPermalink }}" {{ if $isProd }}integrity="{{ $css.Data.Integrity }}"{{ end }} rel="stylesheet" type="text/css" media="{{ $media }}">
{{- end }}
postcss.config.js
You have to adapt your own safelist
and [[params.plugins.css]]
const purgecss = require("@fullhuman/postcss-purgecss")({
content: ["./hugo_stats.json"],
defaultExtractor: (content) => {
const els = JSON.parse(content).htmlElements;
return [...(els.tags || []), ...(els.classes || []), ...(els.ids || [])];
},
safelist: [
// pour bootstrap (Tested OK)
/^btn-/,
// pour swiper + hero (Tested OK)
/^swiper-/,
/^slider-/,
/^aos-/,
/^spinner-/,
// pour scroll (Tested OK)
/^header-/,
// pour instafeed (Tested ??)
/^data-/,
// FOR DOCUMENTATION - USED SOMETIMES BY OTHER COMPONENTS
// pour MsgBox bootstrap (Tested OK)
/collapsing/,
/show/,
/[aria-expanded=true]/,
/[aria-expanded=false]/,
// pour lightbox (Tested OK)
/^lb-/,
/^lightbox/,
/^g/,
/^desc/,
/^zoom/,
/dragging/,
/fullscreen/,
/loaded/,
/visible/,
/current/,
/dragging-nav/,
/inactive/,
/prev/,
],
});
module.exports = {
plugins: [
...(process.env.HUGO_ENVIRONMENT === "production" ? [purgecss] : []),
],
};
config.toml
[build]
writeStats = true
params.toml
# PurgeCSS
purgecss = true
# CSS Plugins
[[params.plugins.css]]
link = "plugins/swiper/swiper-bundle.css"
[[params.plugins.css]]
link = "plugins/glightbox/glightbox.css"
[[params.plugins.css]]
link = "plugins/aos/aos-custom.css"
# for brands
[[params.plugins.css]]
link = "plugins/font-awesome/v6/brands.css"
# load all icons except brands
[[params.plugins.css]]
link = "plugins/font-awesome/v6/icons.css"
# regular icons font family
[[params.plugins.css]]
link = "plugins/font-awesome/v6/regular.css"
# solid icons font family
[[params.plugins.css]]
link = "plugins/font-awesome/v6/solid.css"
modules.toml
[hugoVersion]
extended = true
min = "0.110.0"
[[imports]]
path = "github.com/gohugoio/hugo-mod-bootstrap-scss/v5"
[[imports]]
path = "github.com/gethugothemes/hugo-modules/icons/font-awesome"
etc ...