I think you have to create two seperate form fields to do this in Drupal 8.
You can use textfield
for the title and url
for the URL field, like this:
$form['cta_title'] = [
'#type' => 'textfield',
'#title' => t('CTA Title'),
];
$form['cta_url'] = [
'#type' => 'url',
'#title' => t('CTA Url'),
];
return $form;
Another solution is to pull the widget out from an entity display. There is a guide how to do that here, https://www.webomelette.com/how-render-entity-field-widgets-inside-custom-form-drupal-8.
Basically you load the entity display,
$entity = $this->entityTypeManager->getStorage('node')->create(['type' => 'article']);
$form_display = $this->entityTypeManager->getStorage('entity_form_display')->load('node.article.custom_form_display');
And then you pull out the widgets and add them to your form,
foreach ($form_display->getComponents() as $name => $component) {
$widget = $form_display->getRenderer($name);
if (!$widget) {
continue;
}
$items = $entity->get($name);
$items->filterEmptyItems();
$form[$name] = $widget->form($items, $form, $form_state);
$form[$name]['#access'] = $items->access('edit');
}