diff --git a/configure.ac b/configure.ac
index 92dede80141..a9488967c3f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -255,8 +255,7 @@ dnl Manual pages.
 AM_MISSING_PROG([HELP2MAN], [help2man])
 
 dnl Documentation translation.
-AM_MISSING_PROG([PO4A_TRANSLATE], [po4a-translate])
-AM_MISSING_PROG([PO4A_UPDATEPO], [po4a-updatepo])
+AM_MISSING_PROG([PO4A], [po4a])
 
 case "$storedir" in
   /gnu/store)
diff --git a/doc/local.mk b/doc/local.mk
index 89285b9f35a..68e518a4933 100644
--- a/doc/local.mk
+++ b/doc/local.mk
@@ -5,6 +5,7 @@
 # Copyright © 2016 Taylan Ulrich Bayırlı/Kammer <taylanbayirli@gmail.com>
 # Copyright © 2016, 2018 Mathieu Lirzin <mthl@gnu.org>
 # Copyright © 2018, 2021 Julien Lepiller <julien@lepiller.eu>
+# Copyright © 2023 gemmaro <gemmaro.dev@gmail.com>
 #
 # This file is part of GNU Guix.
 #
@@ -21,32 +22,43 @@
 # You should have received a copy of the GNU General Public License
 # along with GNU Guix.  If not, see <http://www.gnu.org/licenses/>.
 
-# If adding a language, update the following variables, and info_TEXINFOS.
-MANUAL_LANGUAGES = de es fr pt_BR ru zh_CN
-COOKBOOK_LANGUAGES = de fr ko sk
+info_TEXINFOS =					\
+  %D%/guix.texi					\
+  %D%/guix-cookbook.texi			\
+  $(TRANSLATED_INFO_TEXINFOS)
 
-# Arg1: A list of languages codes.
-# Arg2: The file name stem.
-lang_to_texinfo = $(foreach lang,$(1),%D%/$(2).$(lang).texi)
+%C%_guix_TEXINFOS =				\
+  %D%/contributing.texi				\
+  $(TRANSLATED_GUIX_TEXINFOS)			\
+  %D%/fdl-1.3.texi
 
+# If adding a language, update the following and po4a_langs section in
+# po/doc/po4a.cfg.  And if the file name is guix.xx.texi, also update
+# TRANSLATED_GUIX_TEXINFOS.
+#
 # Automake does not understand GNU Make non-standard extensions,
-# unfortunately, so we cannot use the above patsubst-based function here.
-info_TEXINFOS = %D%/guix.texi			\
+# unfortunately, so we cannot use the patsubst-based function here.
+TRANSLATED_INFO_TEXINFOS =			\
   %D%/guix.de.texi				\
   %D%/guix.es.texi				\
   %D%/guix.fr.texi				\
   %D%/guix.pt_BR.texi				\
   %D%/guix.ru.texi				\
   %D%/guix.zh_CN.texi				\
-  %D%/guix-cookbook.texi			\
   %D%/guix-cookbook.de.texi			\
   %D%/guix-cookbook.fr.texi			\
   %D%/guix-cookbook.ko.texi			\
   %D%/guix-cookbook.sk.texi
 
-%C%_guix_TEXINFOS = \
-  %D%/contributing.texi \
-  %D%/fdl-1.3.texi
+TRANSLATED_GUIX_TEXINFOS =			\
+  %D%/contributing.de.texi			\
+  %D%/contributing.es.texi			\
+  %D%/contributing.fr.texi			\
+  %D%/contributing.pt_BR.texi			\
+  %D%/contributing.ru.texi			\
+  %D%/contributing.zh_CN.texi
+
+TRANSLATED_INFO = $(TRANSLATED_INFO_TEXINFOS) $(TRANSLATED_GUIX_TEXINFOS)
 
 DOT_FILES =					\
   %D%/images/bootstrap-graph.dot		\
@@ -76,19 +88,13 @@ OS_CONFIG_EXAMPLES_TEXI =			\
   %D%/os-config-lightweight-desktop.texi	\
   %D%/he-config-bare-bones.scm
 
-TRANSLATED_INFO = 						\
-  $(call lang_to_texinfo,$(MANUAL_LANGUAGES),guix)		\
-  $(call lang_to_texinfo,$(MANUAL_LANGUAGES),contributing)	\
-  $(call lang_to_texinfo,$(COOKBOOK_LANGUAGES),guix-cookbook)
-
 # Bundle this file so that makeinfo finds it in out-of-source-tree builds.
 BUILT_SOURCES        += $(OS_CONFIG_EXAMPLES_TEXI) $(TRANSLATED_INFO)
 EXTRA_DIST           += $(OS_CONFIG_EXAMPLES_TEXI) $(TRANSLATED_INFO)
 MAINTAINERCLEANFILES  = $(OS_CONFIG_EXAMPLES_TEXI) $(TRANSLATED_INFO)
 
-PO4A_PARAMS := -M UTF-8 -L UTF-8 #master and localized encoding
-PO4A_PARAMS += -k 0 # produce an output even if the translation is not complete
-PO4A_PARAMS += -f texinfo # texinfo format
+$(foreach texi,$(TRANSLATED_INFO),$(texi).tmp) &: $(DOC_PO_FILES)
+	-$(AM_V_PO4A)$(PO4A) --no-update $(srcdir)/po/doc/po4a.cfg
 
 # When a change to guix.texi occurs, it is not translated immediately.
 # Because @pxref and @xref commands are references to sections by name, they
@@ -101,22 +107,25 @@ $(top_srcdir)/pre-inst-env $(GUILE) --no-auto-compile	\
   $@.tmp $<
 endef
 
-$(srcdir)/%D%/guix.%.texi: po/doc/guix-manual.%.po $(srcdir)/%D%/contributing.%.texi guix/build/po.go
-	-$(AM_V_PO4A)$(PO4A_TRANSLATE) $(PO4A_PARAMS) -m "%D%/guix.texi" -p "$<" -l "$@.tmp"
+$(srcdir)/%D%/guix.%.texi: po/doc/guix-manual.%.po		\
+		$(srcdir)/%D%/guix.%.texi.tmp			\
+		guix/build/po.go
 	-sed -i "s|guix\.info|$$(basename "$@" | sed 's|texi$$|info|')|" "$@.tmp"
 	-$(AM_V_POXREF)LC_ALL=en_US.UTF-8 $(xref_command)
-	-mv "$@.tmp" "$@"
+	-cp "$@.tmp" "$@"
 
-$(srcdir)/%D%/guix-cookbook.%.texi: po/doc/guix-cookbook.%.po guix/build/po.go
-	-$(AM_V_PO4A)$(PO4A_TRANSLATE) $(PO4A_PARAMS) -m "%D%/guix-cookbook.texi" -p "$<" -l "$@.tmp"
+$(srcdir)/%D%/guix-cookbook.%.texi: po/doc/guix-cookbook.%.po	\
+		$(srcdir)/%D%/guix-cookbook.%.texi.tmp		\
+		guix/build/po.go
 	-sed -i "s|guix-cookbook\.info|$$(basename "$@" | sed 's|texi$$|info|')|" "$@.tmp"
 	-$(AM_V_POXREF)LC_ALL=en_US.UTF-8 $(xref_command)
-	-mv "$@.tmp" "$@"
+	-cp "$@.tmp" "$@"
 
-$(srcdir)/%D%/contributing.%.texi: po/doc/guix-manual.%.po guix/build/po.go
-	-$(AM_V_PO4A)$(PO4A_TRANSLATE) $(PO4A_PARAMS) -m "%D%/contributing.texi" -p "$<" -l "$@.tmp"
+$(srcdir)/%D%/contributing.%.texi: po/doc/guix-manual.%.po	\
+		$(srcdir)/%D%/contributing.%.texi.tmp		\
+		guix/build/po.go
 	-$(AM_V_POXREF)LC_ALL=en_US.UTF-8 $(xref_command)
-	-mv "$@.tmp" "$@"
+	-cp "$@.tmp" "$@"
 
 %D%/os-config-%.texi: gnu/system/examples/%.tmpl
 	$(AM_V_GEN)$(MKDIR_P) "`dirname $@`";	\
diff --git a/po/doc/local.mk b/po/doc/local.mk
index 49258cbb97c..eacd7d8c922 100644
--- a/po/doc/local.mk
+++ b/po/doc/local.mk
@@ -1,6 +1,7 @@
 # GNU Guix --- Functional package management for GNU
 # Copyright © 2018 Julien Lepiller <julien@lepiller.eu>
 # Copyright © 2021 Maxim Cournoyer <maxim.cournoyer@gmail.com>
+# Copyright © 2023 gemmaro <gemmaro.dev@gmail.com>
 #
 # This file is part of GNU Guix.
 #
@@ -17,38 +18,28 @@
 # You should have received a copy of the GNU General Public License
 # along with GNU Guix.  If not, see <http://www.gnu.org/licenses/>.
 
-DOC_PO_FILES =					\
-  %D%/guix-manual.de.po				\
-  %D%/guix-manual.es.po				\
-  %D%/guix-manual.fr.po				\
-  %D%/guix-manual.pt_BR.po			\
-  %D%/guix-manual.ru.po				\
-  %D%/guix-manual.zh_CN.po
+DOC_POT_FILES = %D%/guix-manual.pot %D%/guix-cookbook.pot
 
-DOC_COOKBOOK_PO_FILES =				\
-  %D%/guix-cookbook.de.po			\
-  %D%/guix-cookbook.fr.po			\
-  %D%/guix-cookbook.ko.po			\
+DOC_PO_FILES =						\
+  %D%/guix-manual.de.po					\
+  %D%/guix-manual.es.po					\
+  %D%/guix-manual.fr.po					\
+  %D%/guix-manual.pt_BR.po				\
+  %D%/guix-manual.ru.po					\
+  %D%/guix-manual.zh_CN.po				\
+  %D%/guix-cookbook.de.po				\
+  %D%/guix-cookbook.fr.po				\
+  %D%/guix-cookbook.ko.po				\
   %D%/guix-cookbook.sk.po
 
-EXTRA_DIST = \
-  %D%/guix-manual.pot \
-  %D%/guix-cookbook.pot \
-  $(DOC_PO_FILES) \
-  $(DOC_COOKBOOK_PO_FILES)
+EXTRA_DIST = $(DOC_POT_FILES) $(DOC_PO_FILES)
 
-POT_OPTIONS = \
-	--package-name "guix manual" --package-version "$(VERSION)" 	\
-	--copyright-holder "the authors of Guix (msgids)" 		\
-	--msgid-bugs-address "bug-guix@gnu.org"
+$(DOC_POT_FILES) &: $(srcdir)/doc/guix.texi		\
+		$(srcdir)/doc/guix-cookbook.texi	\
+		$(srcdir)/doc/contributing.texi
+	$(AM_V_PO4A)$(PO4A) --no-translations		\
+		--package-version "$(VERSION)"		\
+		%D%/po4a.cfg
 
-%D%/%.pot: $(srcdir)/doc/%.texi
-	$(AM_V_PO4A)$(PO4A_UPDATEPO) -M UTF-8 -f texinfo -m "$<" \
-	   -p "$@" $(POT_OPTIONS) && \
-	touch $@
-
-%D%/guix-manual.pot: %D%/guix.pot %D%/contributing.pot
-	msgcat $^ > $@
-
-doc-pot-update: %D%/guix-manual.pot %D%/guix-cookbook.pot
+doc-pot-update: $(DOC_POT_FILES)
 .PHONY: doc-pot-update
diff --git a/po/doc/po4a.cfg b/po/doc/po4a.cfg
new file mode 100644
index 00000000000..27a7599d9aa
--- /dev/null
+++ b/po/doc/po4a.cfg
@@ -0,0 +1,42 @@
+# GNU Guix --- Functional package management for GNU
+# Copyright © 2023 gemmaro <gemmaro.dev@gmail.com>
+#
+# This file is part of GNU Guix.
+#
+# GNU Guix is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or (at
+# your option) any later version.
+#
+# GNU Guix is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Guix.  If not, see <http://www.gnu.org/licenses/>.
+
+# --keep 0: produce an output even if the translation is not complete
+[options] --package-name "guix manual"                      \
+          --copyright-holder "the authors of Guix (msgids)" \
+          --msgid-bugs-address "bug-guix@gnu.org"           \
+          --keep 0                                          \
+          --master-charset=UTF-8                            \
+          --localized-charset=UTF-8                         \
+          --destdir=doc
+
+[po4a_langs] de es fr pt_BR ru zh_CN ko sk
+
+[po4a_paths] po/doc/$master.pot $lang:po/doc/$master.$lang.po
+
+[type:texinfo] doc/guix-cookbook.texi                       \
+               $lang:guix-cookbook.$lang.texi.tmp           \
+               pot=guix-cookbook
+
+[type:texinfo] doc/guix.texi                                \
+               $lang:guix.$lang.texi.tmp                    \
+               pot=guix-manual
+
+[type:texinfo] doc/contributing.texi                        \
+               $lang:contributing.$lang.texi.tmp            \
+               pot=guix-manual
