Skip to content

Link Sub-Fields

When to Use

You need full link functionality (URL + title + attributes) within a custom field column.

Pattern

Link column configuration:

columns:
  external_link:
    name: external_link
    type: link

Widget configuration:

$settings['field_settings']['external_link'] = [
  'widget' => 'link',
  'widget_settings' => [
    'placeholder_url' => 'https://example.com',
    'placeholder_title' => 'Link title',
  ],
  // Link field settings
  'link_type' => LinkItemInterface::LINK_GENERIC, // or LINK_INTERNAL, LINK_EXTERNAL
  'title' => DRUPAL_OPTIONAL, // or DRUPAL_REQUIRED, DRUPAL_DISABLED
];

Accessing in code:

$uri = $node->field_custom->external_link; // URI string
$title = $node->field_custom->{'external_link__title'};
$options = $node->field_custom->{'external_link__options'}; // Serialized array

// Render as link
$url = Url::fromUri($uri, $options);
$link = Link::fromTextAndUrl($title ?: $uri, $url)->toRenderable();

Link options array:

[
  'attributes' => [
    'target' => '_blank',
    'rel' => 'noopener noreferrer',
    'class' => ['external-link'],
  ],
]

Decision

If you need... Use... Why
Internal and external links with attributes link type + LinkWidget Full link functionality, attribute support
External URLs only (no title/attributes) uri type + UrlWidget Simpler, just URL validation
URLs with Linkit entity browser link type + custom_field_linkit sub-module Linkit autocomplete for internal links

Common Mistakes

  • Not validating link types -- Configure link_type to restrict internal/external; validation enforces
  • Forgetting to sanitize title -- Link title is user input; sanitize before rendering
  • Not setting rel=noopener for target=_blank -- Security vulnerability; always set noopener noreferrer for external links
  • Using uri type when attributes needed -- uri stores URL only; link type required for target, class, rel

See Also

  • Reference: /modules/contrib/custom_field/src/Plugin/CustomField/FieldWidget/LinkWidget.php
  • Sub-module: custom_field_linkit