This article was originally titled “How can WordPress open links in a new window?” and published in 2014. The old version treated “open every link in a new window” as the goal and recommended editing WordPress core files. Those practices create unexpected context changes and are lost or conflict with newer code during updates, so they should no longer be followed.
The current principle is to leave most links as the browser’s default same-tab navigation, allowing people to choose a middle click, shortcut, or menu when they want a new tab. Request a new browsing context for a specific link only when preserving the current task has real value, and give both a visible and assistive-technology-readable warning before activation. The browser may ultimately use a tab or a window; the site cannot guarantee which.
The complete historical body from
source_exportis preserved at the end. The global<base>and core-file edits inside that archive are historical evidence only and must never be executed.
Table of Contents
Decide between the same tab and a new tab first
| Scenario | Recommendation | Reason and boundary |
|---|---|---|
| On-site articles, categories, navigation, breadcrumbs, and pagination | Same tab | Preserve ordinary history and Back behavior |
| An ordinary external reference | Usually the same tab | “External” alone is not a reason for a new tab; the user can still choose one |
| Help or terms while the user fills an unsaved form | Consider a new tab | Save or protect state first, and warn in the link text |
| A report, evidence, or instructions needed side by side | Consider a new tab | The need should come from task design, not an attempt to retain traffic |
| Sign-in, payment, download, protocol handler, or cross-app action | Design individually | Explain the destination, file type/size, or app launch; a new tab is not a security control |
Do not substitute bounce-rate goals, supposed “SEO authority,” or an “all external links open separately” convention for user research. Link purpose, task continuity, and accessibility are the decision criteria.
Configure one link in the WordPress editor
The current WordPress Link control can enable or disable “Open in new tab” per link. The interface varies slightly by WordPress version, block, and site plugin, so confirm the flow on staging first:
- Select text, an image, or a button and open its Link control.
- Enter or select the complete destination; use an explicit
https://address for another site. - Expand Advanced and enable “Open in new tab” only for the approved link.
- Add a localized warning such as “(opens in a new tab)” to the visible link text.
- Save and inspect the final front-end HTML; the editor toggle is not evidence of the published result.
WordPress checks only whether the address looks valid; it does not guarantee that the page exists or that the destination is trustworthy. The publisher must still verify the final domain, redirects, content owner, and access conditions. Navigation, Button, Image, and third-party blocks may expose the setting elsewhere; if a control lacks it, do not force the behavior with site-wide JavaScript.
Keep the intent explicit in handwritten HTML
An ordinary link needs no target:
<a href="/help/account">Account help</a>
When a new tab is genuinely required, use a fixed HTTPS destination, clear text, and explicit noopener:
<a href="https://example.org/report"
target="_blank"
rel="noopener">Annual report (opens in a new tab)</a>
Modern browsers treat an <a> with target="_blank" as implicitly providing noopener; spelling it out still records the security intent and covers older environments. Do not replace a normal <a href> with window.open(), click handlers, or pseudo-links. Those approaches break address copying, keyboard behavior, and no-script fallback.
| Value | What it means | Usage boundary |
|---|---|---|
target="_blank" | Requests a new browsing context | Does not guarantee a tab rather than a window; warn the user first |
rel="noopener" | Prevents the new context from controlling the source through window.opener | May be explicit on new-tab links; it preserves the normal Referer |
rel="noreferrer" | Omits the Referer and also implies noopener | Use only when privacy policy requires it; assess sign-in, analytics, and attribution effects |
rel="external" | Identifies a destination outside the current site | Relationship semantics only; it is not a security control and does not open a new tab |
rel="nofollow" | Expresses a search relationship such as not endorsing the destination | Unrelated to new tabs and noopener; do not add it in bulk merely because a link is external |
Do not make noreferrer a fixed template, and do not add user identifiers or tracking parameters to URLs for measurement. If link measurement is necessary, define a lawful purpose, minimum data, retention period, and opt-out first.
Let keyboard and screen-reader users know in advance
W3C techniques G201 and H83 both emphasize warning before a link opens a new window or tab. These techniques are possible implementations rather than the only path to conformance, but they explain the real risk: a new context can make the Back button ineffective and disorient people with low vision, screen-reader users, and people with cognitive disabilities.
- Use link text that explains its purpose on its own; avoid repeated “click here” labels and bare URLs.
- Put “opens in a new tab” in the accessible name or provide a reliably associated description; do not rely on an icon without alternative text.
- For a file, also state its format and reasonably known size; warn before launching mail, phone, or another app.
- Preserve the normal Tab sequence and visible focus; do not assign positive
tabindexvalues to links. - Test with keyboard Enter, browser Back, middle-click/shortcuts, and at least one screen reader.
- Never open a new window merely when a control receives focus, a select option changes, or the page loads.
An icon can supplement the visual warning, but do not assume every screen reader announces “new tab” from target automatically. The site’s content must provide the warning, consistently in every language edition.
Security boundaries for external links
A new tab does not make a dangerous destination safe. Every published destination should pass these checks:
- Allow only protocols that the business case explicitly needs; an ordinary webpage should use verified HTTPS, never
javascript:,data:, or an arbitrary user-controlled target. - Follow redirects and verify the final domain, TLS, sign-in requirements, and content; do not trust a short link’s label or appearance.
- Do not put email addresses, account data, session tokens, or internal record numbers into query parameters.
- A theme or plugin that generates HTML must validate the URL and apply context-appropriate escaping on output; never concatenate untrusted attributes.
- Describe a download’s file type, size, and source; do not disguise an executable as an ordinary document.
- Remove a link immediately if its destination is taken over, changes purpose, downgrades to insecure transport, or begins requesting suspicious permissions.
Scheduled link checks should minimize requests and never disclose real user data to destinations. A successful health check proves only that a URL was reachable at that moment, not that its content remains trustworthy.
Make the component that generates a link own the change
| Link source | Correct owner | Safe change location | Do not do this |
|---|---|---|---|
| A single post or page body | Content editor | Use the editor control on the specific link | Rewrite every content link globally |
| Navigation, template, template part, or synced pattern | Site-design owner | Site Editor or a version-controlled child theme | Edit the parent theme or add <base target> |
| Plugin-generated table, directory, comment, or button | Plugin owner | Official setting, documented hook, or an owned plugin | Regex-rewrite final HTML or edit vendor files |
| WordPress admin interface or core output | WordPress core | Accept upstream behavior; file an issue or use a supported extension point if necessary | Edit wp-admin, wp-includes, or core PHP |
| Third-party hosted or embedded content | Service owner and site owner | Review its configuration, sandbox, and contract boundary | Assume theme code can safely control its internal links |
Official WordPress guidance says not to modify core files; core updates overwrite such changes. Parent-theme updates similarly overwrite direct edits, so a necessary theme-level customization belongs in a child theme and version control. Any administrative setting needs appropriate capability and request verification; never let an unauthorized user submit an arbitrary destination or relationship attribute.
Inventory before a bulk migration; do not replace the database directly
Links on a historical site may live in block markup, Classic Editor HTML, navigation, templates, patterns, widgets, comments, options, shortcodes, and plugin-owned tables. One regex replacement cannot determine intent and may corrupt serialized data, block validation, and localized editions.
- Record WordPress, theme, plugin, and PHP versions; create verified, restorable file and database backups.
- On an isolated staging copy, export a link inventory with source object, language, visible text, destination, current
target/rel, final domain, and owner. - Create an explicit allowlist and rationale for each change; preserve the default rather than deciding automatically from “external.”
- Make small batches through the editor, theme, or plugin interface that owns the output, retaining object IDs and before/after values.
- Reparse blocks, purge caches, and run keyboard, assistive-technology, security, and redirect tests for each batch.
- Stop and roll back that batch if the diff exceeds the allowlist, a block becomes invalid, the destination is unclear, or recovery is unavailable.
Do not run search-and-replace directly against production data, alter commenter links to control their target behavior, or accept an arbitrary url parameter in a migration script. A multilingual site must verify warnings and destinations separately for every locale, not just edit the source language.
Test matrix and acceptance evidence
| Test area | Action | Pass condition |
|---|---|---|
| Editor persistence | Toggle one link, save, and reopen it | Control state and front-end HTML agree; no block-validation error |
| Same tab | Normally activate internal and ordinary external links, then use Back | Navigation stays in the expected context and history works |
| New tab | Activate an approved special-case link | A visible and spoken warning precedes activation; exactly one new context appears |
| Keyboard | Use only Tab, Shift+Tab, and Enter | Order is logical, focus is visible, and there is no keyboard trap |
| Screen reader | Browse the link list and activate a sample | Purpose and new-context warning are understandable without excessive repetition |
| Security | Inspect final HTML, redirects, and the new page’s opener | Destination is fixed HTTPS, noopener intent remains, and no sensitive query data exists |
| Responsive and localized | Test mobile and every language | Text is not clipped, warning sounds natural, and destination matches the language |
| Ownership and updates | Update theme/plugin and purge CDN/page cache | The correct component still emits the change; no core or parent-theme drift exists |
Record object IDs, page URLs, test dates, browser/assistive-technology versions, and redacted screenshots. Do not record sign-in tokens, personal browsing history, or commenter identities.
Rollback and stop conditions
For one link, roll back by disabling the editor toggle or removing only that link’s target and no-longer-needed relationship values while retaining the verified href and text. At component scope, restore the previous owned-plugin/child-theme version and database backup, purge caches, and rerun tests. Never treat restoration of an old core patch as rollback.
Stop if any of these occurs: no restorable backup; the link owner cannot be identified; a bulk diff touches objects outside the allowlist; a block becomes invalid after update; purpose or rights are unclear; a redirect crosses to a different domain; the link contains sensitive data; or keyboard/screen-reader users cannot understand the warning. A safe interim state is same-tab behavior or temporarily removing the link, not applying a site-wide patch.
Prepublication checklist
- The destination, final domain, owner, and reason to publish are verified.
- The same-tab or new-tab decision has a recorded reason.
- A new-tab link gives both a visible and assistive-technology warning.
- HTML uses real link semantics, not a scripted pseudo-link.
noopener,noreferrer,external, andnofolloware selected for their separate meanings.- There is no
<base target>, direct core/parent-theme edit, or global DOM rewrite. - No tracking parameter, credential, account detail, or internal identifier leaks.
- Keyboard, screen reader, mobile, localization, and caching scenarios are tested.
- The backup is verified, and the change has an owner, allowlist, and batch rollback record.
- There is a removal process if the link fails, is taken over, or changes behavior.
References
- WordPress: Link control and the “Open in new tab” setting
- WordPress: editing files and avoiding core modifications
- WordPress: child themes and update-safe customization
- MDN: creating links and the new-tab design tradeoff
- MDN: `rel="noopener"`
- MDN: `rel="noreferrer"`
- W3C WAI: G201, warning before opening a new window
- W3C WAI: H83, opening on user request and explaining it in link text
Historical source archive
The following is the complete inert archive of the visible 2014 body in source_export. It has no trailing whitespace or private, credential, referral, or tracking value requiring redaction, so nothing was replaced. The global <base>, core-file edits, and old Links Manager default modification inside the fence are unsafe and unmaintainable historical evidence and must never be executed.
如何让wordpress 在新窗口打开链接?
这个问题开始也一直困扰着我,后来在网上找了找发现有很多的方法,大体上有这么几种:
第一种:wordpress在新窗口打开链接
只要在header.php文件中,标签之间加入以下代码即可:
<base target=”_blank”>
这种方法简单有效,暂时还没有发现什么问题,本博客也是采用的这种方法。
第二种:wordpress在新窗口打开链接
打开wp-admin文件夹,找到admin-header.php文件打开。找到以下代码:
<a href=“<?php echo trailingslashit( get_bloginfo( ‘url’ ) ); ?>” title=“<?php esc_attr_e(‘Visit Site’) ?>” >
在最后一个尖括号”>”前插入target="_blank"。然后保存该文件。这样,在后台打开前台首页的链接就会在新窗口打开了。
添加之后的代码是:
<a href=“<?php echo trailingslashit( get_bloginfo( ‘url’ ) ); ?>” title=“<?php esc_attr_e(‘Visit Site’) ?>” target="_blank" >
第三种:留言评论在新窗口打开链接
首页打开wp-includes文件夹,找到comment-template.php文件打开。找到以下代码:
$return = “<a href=’$url’ rel=’external nofollow’ class=’url’>$author</a>”;
在标签中插入一句[target="_blank"]尖括号中的内容,然后保存。这样,访客昵称所指向的链接就会在新窗口打开了。
添加之后的代码为:
$return = “<a href=’$url’ target="_blank" rel=’external nofollow’ class=’url’>$author</a>”;
第四种:友情链接在新窗口打开链接
打开wp-admin目录下的includes文件夹,找到meta-boxes.php文件打开。找到以下代码:
<input id=“link_target_blank” type=“radio” name=“link_target” value=“_blank” <?php echo
( isset( $link->link_target ) && ($link->link_target == ‘_blank’) ? ‘checked=“checked”‘ : ”); ?> />
将以上代码修改为:
<input id=“link_target_blank” type=“radio” name=“link_target” value=“_blank” checked=“checked” />
这样就可以了。或者是你在添加友情链接时,在最下面有一些选项,可以直接选在新窗口打开链接的。
