At a glance

A subscription URL is the update source, Base64 is an encoding method, a share link describes one node, and core JSON can define an entire runtime configuration. This guide is for anyone whose URL opens in a browser but won’t import into a client: identify the content, choose the right import option in v2rayN or v2rayNG, then check whether conversion would lose routing, DNS, or transport settings.

1. Subscription URLs, Base64, and JSON are different layers

“V2Ray subscription” isn’t a single format defined by a file extension. Typically, a client requests a URL over HTTPS, receives text, parses the nodes in it, and adds them to its configuration list. The URL is used to fetch and update content; the response body determines how that content is parsed. So a missing file extension—or a .txt suffix—doesn’t tell you whether it can be imported.

Subscription URLs and node lists

Recommended

A typical response contains share links on separate lines, or the entire text of those links encoded once with Base64. Keep the subscription URL so you can fetch updated nodes later.

Best for: users who need to keep server lists updated across multiple devices.

Single share link

Prefixes such as vmess:// and vless:// identify the protocol. A link usually contains the connection settings for one node. Importing it typically creates a one-time copy, without subscription updates.

Best for: temporarily moving one node or checking its connection settings individually.

Native core JSON

Can include inbound and outbound connections, DNS, routing, and logging settings. It’s a configuration for a specific core—not the same as a GUI client’s node list or a backup of its data.

Best for: setups that need multiple outbounds, custom routing, or full core settings.

Base64 does not provide encryption. Subscription tokens and node credentials can still be recovered even when they appear as a long string of characters. Don’t submit full subscription content to public conversion sites, and hide query parameters in URLs when sharing screenshots for support.

2. How vmess:// and vless:// links differ

A common VMess share link consists of vmess:// followed by a Base64-encoded JSON object. The object often contains fields such as add, port, id, net, and tls. It describes a node in a share-link format; it is not a complete configuration you can pass directly to Xray to start it.

What to checkCommon VMess link formatCommon VLESS link format
StructureBase64 JSON after the protocol prefixURI user info, host, port, and query parameters
Node identityid in the JSONUser info before @ in the URI
TransportCommon field: netCommon query parameter: type
TLS and server nameCommon fields: tls, sniCommon parameters: security, sni
RemarksCommon field: psFragment after #, usually percent-encoded

A VLESS link usually isn’t “the entire link encoded in Base64 again.” Its parameters may also include flow, fp, pbk, and sid, covering flow control, fingerprinting, and REALITY settings. The exact parameter names and supported values depend on the client version; the protocol prefix alone doesn’t guarantee that every parameter is supported.

3. Decoding Base64 subscriptions—and why some need two decoding steps

Suppose the response body is multiple VMess links joined as text and then Base64-encoded as a whole. The first decode reveals the links, one per line. The payload after each vmess:// still needs to be decoded separately to reveal the node fields. These are two nested encoding layers; not every subscription needs to be decoded twice.

  1. Check the raw content first. If each line already starts with vmess:// or vless://, there’s no need to decode the whole response.
  2. If the content looks like Base64, try decoding it once and check whether the result is a list of links.
  3. If decoding reveals HTML, a sign-in prompt, or an error message, fix the retrieval issue first and stop converting formats.
  4. If the result is JSON, inspect its structure. A JSON array, a core configuration, and an API response aren’t interchangeable just because they’re all valid JSON.

The native JavaScript function below processes text offline; it only encodes and decodes and makes no network requests. It supports common Base64URL characters and uses UTF-8 for Chinese labels. Use it in a trusted local environment, and don’t paste real subscription content into the console on an unfamiliar website.

function decodeBase64Text(source) {
  const normalized = source.trim()
    .replace(/\s+/g, "")
    .replace(/-/g, "+")
    .replace(/_/g, "/");
  const padded = normalized.padEnd(
    Math.ceil(normalized.length / 4) * 4, "="
  );
  const bytes = Uint8Array.from(
    atob(padded), char => char.charCodeAt(0)
  );
  return new TextDecoder("utf-8", { fatal: true }).decode(bytes);
}

function encodeBase64Text(text) {
  const bytes = new TextEncoder().encode(text);
  let binary = "";
  for (const byte of bytes) {
    binary += String.fromCharCode(byte);
  }
  return btoa(binary);
}

How to tell: inspect the decoded result before choosing an import option

If the result is a list of share links, treat it as a node list. If it contains runtime configuration fields such as inbounds and outbounds, check whether it matches the core’s configuration structure. Re-encoding won’t fix an error response or restore missing protocol parameters.

4. Where to import in v2rayN and v2rayNG

GUI clients typically manage server nodes, subscription groups, and custom full configurations separately. Node importers recognize share links; subscription settings store update URLs; custom configuration options handle full JSON files. Don’t paste all three kinds of content into the subscription URL field.

Import options: choose the desktop or Android workflow that matches your content

Desktop: v2rayN
  • One or more share links: copy them, then select “Servers” → “Import batch URLs from clipboard.”
  • Subscription URL: select “Subscription Group” → “Subscription Group Settings,” add the URL, then update the subscription.
  • Full JSON: find the custom configuration server option in the “Servers” menu and select the core that matches the configuration.
Android: v2rayNG
  • Share links: tap “+” in the top-right corner → “Import config from clipboard.”
  • Subscription URL: open “Subscription settings” in the side menu, add a group and URL, then return to the list and select “Update subscription.”
  • Full JSON: use the custom configuration import option in the “+” menu. Don’t import it as a regular node link.

These are common menu labels and may vary slightly by version. Use the clipboard, subscription group, and custom configuration options available in your current version.

v2rayNG uses the Xray core, while v2flyNG uses the V2Fly core. A JSON config that works in v2rayNG won’t necessarily work unchanged in v2flyNG. Check compatibility with the target core, especially for REALITY, specific transport settings, and core-specific fields.

5. Converting between formats—and what doesn’t carry over

Converting between share links and Base64 subscriptions usually changes only the outer wrapper: join complete links with line breaks, then encode the text as UTF-8 Base64 to create a typical static subscription body. But the body alone isn’t an updatable subscription service; the client still needs a URL to fetch it and a mechanism to maintain its content.

ConversionHow to do itMain limitation
Base64 subscription → share linksDecode the entire body once, preserving each link and its line breakThe body can’t restore the original subscription token, update interval, or API response headers
Share links → Base64 bodyPut one complete link on each line, encode as UTF-8, then Base64-encode the whole textStatic content won’t update automatically with the original subscription
Share links → core JSONParse the protocol, security, and transport settings, then generate the corresponding outboundYou’ll still need to configure inbounds, routing, DNS, and other runtime settings
Full JSON → share linkChoose one representable remote outbound and map its settings field by fieldMultiple outbounds, routing rules, and full DNS policies usually can’t be preserved

When converting JSON, don’t just extract the server, port, and identity fields. For WebSocket over TLS, also check the transport type, path, Host, TLS setting, and SNI. For VLESS with REALITY, check the public key, short ID, and related flow-control settings. If anything is missing, the client may report a successful import while the connection still fails.

  1. Check the input structure first: VMess JSON in a share link and an object in the core’s outbounds use different fields.
  2. Choose the target next: If the full configuration has multiple remote outbounds, decide which one to export. Don’t mistake a direct or blocked outbound for a node.
  3. Compare settings individually: After importing into the target client, open the edit screen and check the security, transport path, and protocol-specific fields.
  4. Test last: First confirm the core starts, then test a request. A working node doesn’t mean the original routing behavior has been restored.

Migration tip: keep the full configuration to preserve routing

If you only need to move a server list, share links may be enough. To reproduce the original DNS and routing behavior, keep the full JSON and check compatibility with the target core. Don’t treat share links as a backup of the entire configuration.

6. Subscription and conversion FAQs

Why does the subscription open in a browser but show zero nodes in the client?

First check whether the response is actually a link list or its Base64-encoded form. The browser may be signed in while the client receives a login page; the server may also return different content depending on the request. Make sure the URL in the subscription group is complete, then confirm the service provider’s format is supported by your client.

The decoded labels are garbled. Can I still import the content?

Decode as UTF-8 first; don’t treat the result of atob() as a Unicode string. If only the labels are corrupted, the connection fields may still be intact, but check the original content again. If the path or query parameters are also corrupted, stop and don’t test with invalid settings.

Why won’t a syntactically valid full JSON config start?

A JSON syntax check only validates the structure, such as quotes and commas. Next, check the core log for the specific field path. Look for fields unsupported by the target core, missing runtime settings, or a local port conflict. Re-encoding as Base64 won’t fix startup errors.

Why did nodes stop updating after I converted the subscription to share links?

Importing from the clipboard usually creates a copy of the current nodes without retaining the subscription URL they came from. To keep them updated, save the original subscription URL under “Subscription Group Settings” and update from that group. Also keep in mind that manual changes to nodes in a group may be overwritten by the next update.

Can converting the format make an older core support new parameters?

No. Conversion changes how settings are represented; it doesn’t add core capabilities. Note the actual client and core versions, then check support for the target protocol, security, and transport settings. If you encounter unknown fields, update to a compatible version or request a compatible config from the server provider rather than deleting important parameters at random.

A reliable workflow is to identify what you received, choose the matching import option, then check the protocol settings and core logs. Treat retrieval failures, format mismatches, and connection configuration errors as separate issues; that’s more effective than repeatedly changing the encoding.