I recently came across a situation where I had to add a class to a link field in a content type. Now, this can be done using contributed modules like Link Attributes widget or Advance Link Attributes.

However, there was a small catch in the requirement. The extra class has to be added only for external URLs added via the Link field. Now, although updating the field widget to add an extra field for class seems to be a solution but it's not author-friendly when the users base are non-technical editors.

So, instead of adding any new module or a new field widget, I ended up writing a small preprocess for the field to check if the field item URL is external then add the external class.


/**
 * Implements hook_preprocess_field().
 */
function mars_preprocess_field(&$variables) {
  $element = $variables['element'];

  // Check if the field is the target field.
  if ($element['#field_name'] == 'field_related_articles') {

    // Iterate through the field items.
    foreach($variables['items'] as $key => $item) {

      // Clone the \Drupal\Core\Url object to a variable.
      $url = clone $item['content']['#url'];

      // Check if the URL is external then add the class.
      if($url->isExternal()) {
        $variables['items'][$key]['content']['#options']['attributes']['class'][] = 'ext-link';
      }
    }
  }
}

This can be achieved using JavaScript as well by checking all the href attributes of the field items on load, but should be avoided. It's always better to look out if Drupal is providing any API or hook to do what is intended. Usage of JavaScript for such purposes should be used as a last resort.