{"record":{"id":"d7d7e47c4785b51f","repo":"HandyOrg/HandyControl","slug":"tabs-block-must-have-unique-name","errorCode":null,"errorMessage":"Tabs block must have unique name!","messagePattern":"Tabs block must have unique name!","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"doc/themes/next/scripts/tags/tabs.js","lineNumber":22,"sourceCode":"\n/* global hexo */\n\n'use strict';\n\nfunction postTabs(args, content) {\n  var tabBlock = /<!--\\s*tab (.*?)\\s*-->\\n([\\w\\W\\s\\S]*?)<!--\\s*endtab\\s*-->/g;\n\n  args = args.join(' ').split(',');\n  var tabName = args[0];\n  var tabActive = Number(args[1]) || 0;\n\n  var matches = [];\n  var match;\n  var tabId = 0;\n  var tabNav = '';\n  var tabContent = '';\n\n  !tabName && hexo.log.warn('Tabs block must have unique name!');\n\n  while ((match = tabBlock.exec(content)) !== null) {\n    matches.push(match[1]);\n    matches.push(match[2]);\n  }\n\n  for (var i = 0; i < matches.length; i += 2) {\n    var tabParameters = matches[i].split('@');\n    var postContent   = matches[i + 1];\n    var tabCaption    = tabParameters[0] || '';\n    var tabIcon       = tabParameters[1] || '';\n    var tabHref       = '';\n\n    postContent = hexo.render.renderSync({text: postContent, engine: 'markdown'}).trim();\n\n    tabId += 1;\n    tabHref = (tabName + ' ' + tabId).toLowerCase().split(' ').join('-');\n","sourceCodeStart":4,"sourceCodeEnd":40,"githubUrl":"https://github.com/HandyOrg/HandyControl/blob/2c0875ebd67326e0c67282967e3e809c69282fee/doc/themes/next/scripts/tags/tabs.js#L4-L40","documentation":"The NexT theme's tabs Hexo tag warns when the tabs block name (the first argument or the Unique name after '@') is missing. The warning is non-fatal — tabId falls back to 0 and rendering continues — but duplicate or missing names can break tab switching and anchor uniqueness across the page.","triggerScenarios":"Using {% tabs %} ... {% endtabs %} with no name argument, so tabName is empty; the tag expects {% tabs Unique name %} or {% tabs name, index %}.","commonSituations":"Authors copying the closing {% endtabs %} correctly but forgetting the name after {% tabs %}, or using tabs blocks with identical names on one page causing id collisions.","solutions":["Add a unique name as the first argument: {% tabs Unique name %}.","Give every tabs block on the page a distinct name to avoid duplicate ids.","Optionally pass a pre-selected tab index as the second argument ({% tabs name, 1 %})."],"exampleFix":"// before\n{% tabs %}\n<!-- tab -->\ncontent\n{% endtabs %}\n// after\n{% tabs Demo Tab %}\n<!-- tab -->\ncontent\n{% endtabs %}","handlingStrategy":"validation","validationCode":"function checkTabsArgs(rawArgs) {\n  const name = rawArgs.join(' ').split(',')[0].trim();\n  if (!name) {\n    console.warn('{% tabs %} requires a unique name: {% tabs Unique name %}');\n    return false;\n  }\n  return true;\n}","typeGuard":"function hasTabName(args) {\n  const name = args.join(' ').split(',')[0];\n  return typeof name === 'string' && name.trim().length > 0;\n}","tryCatchPattern":null,"preventionTips":["Always name tabs blocks: {% tabs Some unique name %}.","Ensure names are unique within each page so generated tab ids do not collide.","Add a lint rule that flags `{% tabs %}` immediately followed by whitespace/newline."],"tags":["hexo","theme","missing-argument","markdown"],"backgroundTag":"missing-required-argument","analyzedSha":"2c0875ebd67326e0c67282967e3e809c69282fee","analyzedAt":"2026-09-14T14:45:29.754Z","contentChangedAt":"2026-09-14T14:45:29.754Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}