Index: /trunk/src/org/openstreetmap/josm/gui/dialogs/properties/PropertiesDialog.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/dialogs/properties/PropertiesDialog.java	(revision 16596)
+++ /trunk/src/org/openstreetmap/josm/gui/dialogs/properties/PropertiesDialog.java	(revision 16597)
@@ -192,7 +192,7 @@
     private final HelpAction helpTagAction = new HelpTagAction(tagTable, editHelper::getDataKey, editHelper::getDataValues);
     private final HelpAction helpRelAction = new HelpMembershipAction(membershipTable, x -> (IRelation<?>) membershipData.getValueAt(x, 0));
-    private final TaginfoAction taginfoAction = new TaginfoAction(tr("Go to Taginfo"),
+    private final TaginfoAction taginfoAction = new TaginfoAction(
             tagTable, editHelper::getDataKey, editHelper::getDataValues,
-            membershipTable, x -> (IRelation<?>) membershipData.getValueAt(x, 0), null);
+            membershipTable, x -> (IRelation<?>) membershipData.getValueAt(x, 0));
     private final TaginfoAction tagHistoryAction = taginfoAction.toTagHistoryAction();
     private final Collection<TaginfoAction> taginfoNationalActions = new ArrayList<>();
@@ -375,7 +375,5 @@
             final LatLon center = newSel.iterator().next().getBBox().getCenter();
             Territories.getRegionalTaginfoUrls(center).stream()
-                    .map(taginfo -> new TaginfoAction(tr("Go to Taginfo ({0})", taginfo.toString()),
-                            tagTable, editHelper::getDataKey, editHelper::getDataValues,
-                            membershipTable, x -> (IRelation<?>) membershipData.getValueAt(x, 0), taginfo.getUrl())
+                    .map(taginfo -> taginfoAction.withTaginfoUrl(tr("Go to Taginfo ({0})", taginfo.toString()), taginfo.getUrl())
                     ).forEach(taginfoNationalActions::add);
             taginfoNationalActions.stream().map(membershipMenu::add).forEach(membershipMenuTagInfoNatItems::add);
Index: /trunk/src/org/openstreetmap/josm/gui/dialogs/properties/TaginfoAction.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/dialogs/properties/TaginfoAction.java	(revision 16596)
+++ /trunk/src/org/openstreetmap/josm/gui/dialogs/properties/TaginfoAction.java	(revision 16597)
@@ -35,7 +35,7 @@
     private TaginfoAction(String name, Supplier<Tag> tagSupplier, Supplier<String> relationTypeSupplier, String taginfoUrl) {
         super(name);
-        this.tagSupplier = tagSupplier;
-        this.relationTypeSupplier = relationTypeSupplier;
-        this.taginfoUrl = taginfoUrl;
+        this.tagSupplier = Objects.requireNonNull(tagSupplier);
+        this.relationTypeSupplier = Objects.requireNonNull(relationTypeSupplier);
+        this.taginfoUrl = withoutTrailingSlash(Objects.requireNonNull(taginfoUrl));
     }
 
@@ -47,15 +47,10 @@
      */
     public TaginfoAction(Supplier<Tag> tagSupplier, Supplier<String> relationTypeSupplier) {
-        super(tr("Go to Taginfo"));
+        this(tr("Go to Taginfo"), tagSupplier, relationTypeSupplier, TAGINFO_URL_PROP.get());
         new ImageProvider("dialogs/taginfo").getResource().attachImageIcon(this, true);
-        putValue(SHORT_DESCRIPTION, tr("Launch browser with Taginfo statistics for selected object"));
-        this.tagSupplier = Objects.requireNonNull(tagSupplier);
-        this.relationTypeSupplier = Objects.requireNonNull(relationTypeSupplier);
-        this.taginfoUrl = getTaginfoUrl(null);
     }
 
     /**
      * Constructs a new {@code TaginfoAction} with a given URL and optional name suffix.
-     * @param name the action's text as displayed on the menu (if it is added to a menu)
      * @param tagTable The tag table. Cannot be null
      * @param tagKeySupplier Finds the key from given row of tag table. Cannot be null
@@ -63,17 +58,17 @@
      * @param membershipTable The membership table. Can be null
      * @param memberValueSupplier Finds the parent relation from given row of membership table. Can be null
-     * @param taginfoUrl Taginfo URL. Can be null
-     * @since 15565
+     * @since 16597
      */
-    public TaginfoAction(String name, JTable tagTable, IntFunction<String> tagKeySupplier, IntFunction<Map<String, Integer>> tagValuesSupplier,
-                         JTable membershipTable, IntFunction<IRelation<?>> memberValueSupplier, String taginfoUrl) {
-        super(name);
-        new ImageProvider("dialogs/taginfo").getResource().attachImageIcon(this, true);
-        putValue(SHORT_DESCRIPTION, tr("Launch browser with Taginfo statistics for selected object"));
-        this.taginfoUrl = getTaginfoUrl(taginfoUrl);
+    public TaginfoAction(JTable tagTable, IntFunction<String> tagKeySupplier, IntFunction<Map<String, Integer>> tagValuesSupplier,
+                         JTable membershipTable, IntFunction<IRelation<?>> memberValueSupplier) {
+        this(getTagSupplier(tagTable, tagKeySupplier, tagValuesSupplier),
+                getRelationTypeSupplier(membershipTable, memberValueSupplier));
+    }
+
+    private static Supplier<Tag> getTagSupplier(JTable tagTable, IntFunction<String> tagKeySupplier, IntFunction<Map<String, Integer>> tagValuesSupplier) {
         Objects.requireNonNull(tagTable);
         Objects.requireNonNull(tagKeySupplier);
         Objects.requireNonNull(tagValuesSupplier);
-        this.tagSupplier = () -> {
+        return () -> {
             if (tagTable.getSelectedRowCount() == 1) {
                 final int row = tagTable.getSelectedRow();
@@ -85,5 +80,8 @@
             return null;
         };
-        this.relationTypeSupplier = () -> membershipTable != null && membershipTable.getSelectedRowCount() == 1
+    }
+
+    private static Supplier<String> getRelationTypeSupplier(JTable membershipTable, IntFunction<IRelation<?>> memberValueSupplier) {
+        return () -> membershipTable != null && membershipTable.getSelectedRowCount() == 1
                 ? memberValueSupplier.apply(membershipTable.getSelectedRow()).get("type") : null;
     }
@@ -100,11 +98,4 @@
             OpenBrowser.displayUrl(getTaginfoUrlForRelationType(type));
         }
-    }
-
-    private static String getTaginfoUrl(String taginfoUrl) {
-        if (taginfoUrl == null) {
-            taginfoUrl = TAGINFO_URL_PROP.get();
-        }
-        return withoutTrailingSlash(taginfoUrl);
     }
 
@@ -136,4 +127,16 @@
 
     /**
+     * Returns a new action which launches the Taginfo instance from the given URL
+     * @param name the action's text as displayed on the menu (if it is added to a menu)
+     * @param taginfoUrl Taginfo URL
+     * @since 16597
+     */
+    public TaginfoAction withTaginfoUrl(String name, String taginfoUrl) {
+        TaginfoAction action = new TaginfoAction(name, tagSupplier, relationTypeSupplier, taginfoUrl);
+        new ImageProvider("dialogs/taginfo").getResource().attachImageIcon(action, true);
+        return action;
+    }
+
+    /**
      * Returns a new action which launches https://taghistory.raifer.tech/ for the given tag
      * @return a new action
@@ -141,5 +144,5 @@
      */
     public TaginfoAction toTagHistoryAction() {
-        String url = withoutTrailingSlash(TAG_HISTORY_URL_PROP.get());
+        String url = TAG_HISTORY_URL_PROP.get();
         return new TaginfoAction(tr("Go to OSM Tag History"), tagSupplier, relationTypeSupplier, url) {
             @Override
Index: /trunk/src/org/openstreetmap/josm/gui/history/TagInfoViewer.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/history/TagInfoViewer.java	(revision 16596)
+++ /trunk/src/org/openstreetmap/josm/gui/history/TagInfoViewer.java	(revision 16597)
@@ -1,6 +1,4 @@
 // License: GPL. For details, see LICENSE file.
 package org.openstreetmap.josm.gui.history;
-
-import static org.openstreetmap.josm.tools.I18n.tr;
 
 import java.awt.event.FocusEvent;
@@ -100,5 +98,5 @@
         tagMenu.addSeparator();
         tagMenu.add(trackJosmAction(new HelpTagAction(table, tagKeyFn, tagValuesFn)));
-        TaginfoAction taginfoAction = new TaginfoAction(tr("Go to Taginfo"), table, tagKeyFn, tagValuesFn, null, null, null);
+        TaginfoAction taginfoAction = new TaginfoAction(table, tagKeyFn, tagValuesFn, null, null);
         tagMenu.add(trackJosmAction(taginfoAction.toTagHistoryAction()));
         tagMenu.add(trackJosmAction(taginfoAction));
Index: /trunk/test/unit/org/openstreetmap/josm/gui/dialogs/properties/TaginfoActionTest.java
===================================================================
--- /trunk/test/unit/org/openstreetmap/josm/gui/dialogs/properties/TaginfoActionTest.java	(revision 16596)
+++ /trunk/test/unit/org/openstreetmap/josm/gui/dialogs/properties/TaginfoActionTest.java	(revision 16597)
@@ -4,4 +4,6 @@
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNull;
+
+import javax.swing.Action;
 
 import org.junit.Rule;
@@ -36,4 +38,14 @@
      */
     @Test
+    public void testCustomInstance() {
+        TaginfoAction action = new TaginfoAction(() -> null, () -> null).withTaginfoUrl("example.com", "https://taginfo.example.com////");
+        assertEquals("example.com", action.getValue(Action.NAME));
+        assertEquals("https://taginfo.example.com/keys/railway", action.getTaginfoUrlForTag(new Tag("railway")));
+    }
+
+    /**
+     * Unit test of {@link TaginfoAction#toTagHistoryAction()}
+     */
+    @Test
     public void testTagHistoryUrls() {
         TaginfoAction action = new TaginfoAction(() -> null, () -> null).toTagHistoryAction();
