Saltar para o conteúdo
Como criar ícones SVG personalizados no WordPress 7.1
Inês Silva
Inês Silva 14 dEurope/Budapest August dEurope/Budapest 2026 · 16 min de leitura

Como criar ícones SVG personalizados no WordPress 7.1

O WordPress 7.1 está a introduzir uma API pública para ícones SVG personalizados. Com ela, um plugin pode registar coleções e ícones que surgem no seletor do bloco core/icon, que se renderizam em PHP e que ficam disponíveis através da REST API, sem JavaScript nem processo de build.

Este guia cria um plugin mínimo que regista uma coleção, adiciona SVGs embebidos e ficheiros SVG, carrega automaticamente uma pasta inteira de ícones e reutiliza-os no editor, em templates PHP, shortcodes e ícones de blocos.

Requisitos

O WordPress 7.1 tem lançamento previsto para 19 de agosto de 2026. Para desenvolveres antes dessa data, podes usar o WordPress 7.1 RC.

  • WordPress 7.1 ou posterior.
  • Alguns ficheiros de ícones SVG.
  • Um ambiente de desenvolvimento local, como LocalWP, WordPress Studio ou wp-env.
  • Conhecimentos básicos de PHP.

A API de ícones em três funções

A API assenta em três funções e no conceito de coleção. Uma coleção é um grupo nomeado de ícones; o respetivo nome funciona como namespace, evitando colisões entre os ícones do core, os de outros plugins e os teus.

  • wp_register_icon_collection( $name, $args ) regista uma coleção de ícones com nome.
  • wp_register_icon( $name, $args ) regista um ícone individual.
  • wp_get_icon( $name, $args ) devolve a string SVG de um ícone para a renderizares em PHP.

Cada ícone tem de pertencer a uma coleção. Por isso, core/plus e myplugin/plus podem coexistir: o prefixo da coleção torna o nome completo único.

Ao registares cada ícone, fornece o SVG através de content, com o markup SVG numa string PHP, ou através de file_path, com o caminho absoluto para um ficheiro .svg. Usa apenas uma destas opções em cada ícone: content é prático para um ou dois SVGs, enquanto file_path adapta-se melhor a bibliotecas guardadas numa pasta.

Criar o plugin e registar a coleção

A coleção tem de existir antes de tentares acrescentar-lhe ícones. Se registares um ícone para uma coleção inexistente, este não aparece no seletor, sem que o WordPress apresente um erro visível.

Dentro de wp-content/plugins/, cria esta estrutura:

myplugin-custom-icons/
├── myplugin-custom-icons.php
└── icons/
    ├── star.svg
    └── bookmark.svg

No ficheiro principal, adiciona o cabeçalho do plugin, impede o acesso direto e regista a coleção no hook init. A prioridade predefinida deste hook é 10.

<?php
/**
 * Plugin Name: MyPlugin Custom Icons
 * Description: Regista ícones SVG personalizados para WordPress 7.1+.
 * Version:     1.0.0
 * Author:      MyPlugin
 * Requires at least: 7.1
 * Requires PHP: 7.4
 */

if ( ! defined( 'ABSPATH' ) ) {
    exit;
}

define( 'MYPLUGIN_ICONS_PATH', plugin_dir_path( __FILE__ ) );

/**
 * Regista a coleção antes dos respetivos ícones.
 */
add_action( 'init', 'myplugin_register_icon_collection' );

function myplugin_register_icon_collection() {
    wp_register_icon_collection(
        'myplugin',
        array(
            'label' => __( 'MyPlugin', 'myplugin-icons' ),
        )
    );
}

O nome myplugin passa a ser o prefixo de todos os ícones, como myplugin/heart, myplugin/star e myplugin/bookmark. A etiqueta label aparece como título da secção no seletor de ícones; depois de ativares o plugin em Plugins > Plugins instalados, a coleção continua invisível até conter pelo menos um ícone.

Registar SVGs embebidos e a partir de ficheiros

Ícone embebido com content

Se só precisares de um ou dois ícones, podes manter o SVG diretamente no PHP. Regista o coração com prioridade 20, garantindo que a coleção criada na prioridade 10 já está disponível.

/**
 * Regista um ícone com o conteúdo SVG embebido.
 */
add_action( 'init', 'myplugin_register_inline_icons', 20 );

function myplugin_register_inline_icons() {
    wp_register_icon(
        'myplugin/heart',
        array(
            'label'   => __( 'Heart', 'myplugin-icons' ),
            'content' => '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"/></svg>',
        )
    );
}

O nome segue sempre o formato colecao/slug-do-icone. A etiqueta aparece no seletor e content contém o markup; como o SVG usa stroke="currentColor", herda a cor do texto envolvente em vez de fixar uma cor própria.

Ícones em ficheiros com file_path

Para os ícones guardados no disco, coloca estes ficheiros na pasta icons/. O WordPress lê o ficheiro quando precisa de o renderizar.

<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
    <polygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2"/>
</svg>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
    <path d="M19 21l-7-5-7 5V5a2 2 0 0 1 2-2h10a2 2 0 0 1 2 2z"/>
</svg>
/**
 * Regista ícones a partir de ficheiros .svg.
 */
add_action( 'init', 'myplugin_register_file_icons', 20 );

function myplugin_register_file_icons() {
    wp_register_icon(
        'myplugin/star',
        array(
            'label'     => __( 'Star', 'myplugin-icons' ),
            'file_path' => MYPLUGIN_ICONS_PATH . 'icons/star.svg',
        )
    );

    wp_register_icon(
        'myplugin/bookmark',
        array(
            'label'     => __( 'Bookmark', 'myplugin-icons' ),
            'file_path' => MYPLUGIN_ICONS_PATH . 'icons/bookmark.svg',
        )
    );
}

Abre agora o bloco core/icon no editor. O seletor mostra uma secção MyPlugin com Heart, Star e Bookmark, e podes inserir qualquer um deles sem código adicional.

Seletor do bloco de ícones com ícones SVG personalizados adicionados
Os ícones registados surgem numa secção própria do seletor do bloco core/icon. — Forrás: WPVibes

Falha mais comum

Se um ícone não aparecer, confirma primeiro a ordem de registo. Regista a coleção em init com a prioridade predefinida e os ícones numa prioridade posterior, como 20.

Registar automaticamente todos os SVGs de uma pasta

Uma biblioteca real não deve obrigar-te a escrever dezenas de chamadas a wp_register_icon(). Em vez de manteres os dois registos individuais anteriores, substitui a função myplugin_register_file_icons() por uma função que procura todos os .svg da pasta em cada pedido.

add_action( 'init', 'myplugin_register_all_file_icons', 20 );

function myplugin_register_all_file_icons() {
    $icons_dir = MYPLUGIN_ICONS_PATH . 'icons/';
    $svg_files = glob( $icons_dir . '*.svg' );

    if ( empty( $svg_files ) ) {
        return;
    }

    foreach ( $svg_files as $file_path ) {
        $slug  = basename( $file_path, '.svg' );
        $label = ucwords( str_replace( '-', ' ', $slug ) );

        wp_register_icon(
            'myplugin/' . $slug,
            array(
                'label'     => $label,
                'file_path' => $file_path,
            )
        );
    }
}

glob( $icons_dir . '*.svg' ) devolve todos os SVGs da pasta. Depois, basename( $file_path, '.svg' ) remove o caminho e a extensão, pelo que advanced-button.svg passa a advanced-button; por fim, ucwords( str_replace( '-', ' ', $slug ) ) converte-o numa etiqueta legível, Advanced Button.

O ciclo regista cada resultado na coleção myplugin/. Basta colocares outro SVG em icons/, atualizares o editor e o ícone fica disponível, sem alterações ao PHP; este padrão escala de poucos ícones para centenas e pode coexistir com o coração registado diretamente em content.

Vários ícones SVG personalizados disponíveis no seletor de ícones
O registo em lote permite preencher a coleção a partir de todos os SVGs de uma pasta. — Forrás: WPVibes

Usar os ícones no editor, em PHP e nos blocos

No bloco core/icon e na REST API

Todas as coleções registadas aparecem automaticamente no seletor do bloco core/icon; quem está a editar insere o bloco, escolhe o ícone e este renderiza-se no frontend. Os ícones ficam também expostos em /wp-json/wp/v2/icons e as coleções no endpoint complementar /wp-json/wp/v2/icon-collections, permitindo que ferramentas externas consultem os dados do WordPress.

Em templates PHP com wp_get_icon()

wp_get_icon() devolve o SVG numa string, pelo que podes imprimi-la diretamente. Esta é a forma mais simples de renderizar o coração:

echo wp_get_icon( 'myplugin/heart' );

Num template, passa um segundo array para definires o tamanho, uma classe CSS e uma etiqueta acessível.

echo wp_get_icon(
    'myplugin/star',
    array(
        'size'  => 32,
        'class' => 'featured-icon',
        'label' => __( 'Featured', 'myplugin-icons' ),
    )
);
  • size define width e height do SVG em píxeis.
  • class acrescenta uma classe CSS ao elemento SVG.
  • label define aria-label para leitores de ecrã.

Além destes argumentos, o array $args de wp_get_icon() aceita title. Podes envolver a string devolvida no teu próprio HTML quando precisares de uma estrutura diferente.

Criar um shortcode

O shortcode seguinte permite inserir qualquer ícone registado no conteúdo de artigos, páginas ou widgets. Sanitiza o nome, o tamanho e a classe antes de chamar wp_get_icon(); se o ícone não existir, devolve uma string vazia.

add_shortcode( 'myplugin_icon', 'myplugin_icon_shortcode' );

function myplugin_icon_shortcode( $atts ) {
    $atts = shortcode_atts(
        array(
            'name'  => 'heart',
            'text'  => '',
            'size'  => 24,
            'class' => '',
        ),
        $atts
    );

    $icon = wp_get_icon(
        'myplugin/' . sanitize_key( $atts['name'] ),
        array(
            'size'  => absint( $atts['size'] ),
            'class' => sanitize_html_class( $atts['class'] ),
        )
    );

    if ( ! $icon ) {
        return '';
    }

    return sprintf(
        '<span>%s %s</span>',
        $icon,
        esc_html( $atts['text'] )
    );
}
[myplugin_icon name="heart" text="Hello World"]

[myplugin_icon name="star" text="Featured post" size="32"]

[myplugin_icon name="bookmark" text="Save for later" size="20"]

O SVG fica ao lado do texto e respeita o atributo size. Por usar currentColor, adota automaticamente a cor do texto à volta.

Como ícone de um bloco personalizado

Podes substituir o Dashicon predefinido de um bloco pelo nome completo de um ícone registado. No array de register_block_type(), troca a chave icon desta forma:

'icon' => 'warning', // Usa um Dashicon
'icon' => 'myplugin/star', // Usa um ícone SVG personalizado registado

O inseridor de blocos mostra então o SVG personalizado em vez de um Dashicon genérico. Esta opção funciona tanto com blocos registados em JavaScript como com blocos registados apenas em PHP.

Estilizar ícones SVG personalizados

Os ícones podem parecer nativos quando se adaptam à cor, ao tamanho e aos estados da interface. A classe passada em wp_get_icon() dá-te um seletor direto para o SVG; no seletor do editor, onde esse argumento não é usado, aplicam-se os mesmos princípios através de estilos adequados ao contexto.

Herdar a cor com currentColor

Usa stroke="currentColor" ou fill="currentColor", nunca uma cor fixa, para que o SVG se comporte como texto. Um ícone dentro de texto vermelho fica vermelho, num tema escuro acompanha essa aparência e numa ligação usa a cor da própria ligação.

<!-- Evita uma cor fixa: o ícone ficará sempre vermelho. -->
<svg viewBox="0 0 24 24"
     stroke="#dc2626"
     stroke-width="2">
    <path d="..." />
</svg>

Retira as cores fill e stroke codificadas, bem como os atributos width e height do elemento <svg> de raiz, mantendo o viewBox e os atributos estruturais. Remove também blocos <style>, scripts e tudo o que não seja necessário.

Forçar uma cor específica

Por vezes um ícone tem de manter uma cor própria, como acontece com uma marca ou um indicador de estado. Como o SVG usa currentColor, definir color na classe do SVG propaga a cor para o seu stroke ou fill.

.featured-icon {
    color: #f59e0b; /* Âmbar, independentemente do texto envolvente. */
}

Dimensionamento e estados hover

Para uma utilização isolada com dimensão exata, passa size a wp_get_icon() ou ao shortcode. Se o ícone aparece em vários sítios, ou se o estilo depende de estados como hover, focus e active, usa classes CSS no SVG ou no elemento que o envolve.

.myplugin-icon-inline svg {
    transition: transform 0.15s ease-in-out;
}

.myplugin-icon-inline:hover svg {
    transform: scale(1.1);
}

No shortcode, pequenos ajustes locais usam o atributo size; para manteres um estilo consistente em todo o site, aplica regras CSS a um seletor como .myplugin-icon-inline svg.

Remover ícones e coleções

O WordPress 7.1 inclui funções simétricas para anular o registo de um ícone individual ou de uma coleção inteira. Durante o desenvolvimento, ou se uma atualização deixar de disponibilizar um ícone, remove-o assim:

wp_unregister_icon( 'myplugin/bookmark' );

O ícone desaparece do seletor no pedido seguinte. Os artigos que já o tinham inserido num bloco core/icon passam a renderizar vazios, porque o WordPress não reescreve o conteúdo guardado.

Quando desativas o plugin, remove a coleção completa para que todos os seus ícones deixem de surgir no seletor. Não precisas de percorrer cada ícone individualmente.

register_deactivation_hook( __FILE__, 'myplugin_unregister_icons' );

function myplugin_unregister_icons() {
    wp_unregister_icon_collection( 'myplugin' );
}

Perguntas frequentes

Tenho de registar uma coleção antes dos ícones?

Sim. Cada ícone tem de pertencer a uma coleção existente; caso contrário, não aparece no seletor. Regista a coleção em init na prioridade predefinida e os ícones numa prioridade superior, como 20.

Posso misturar content e file_path na mesma coleção?

Sim. Cada chamada a wp_register_icon() é independente. Usa content para um ou dois ícones e file_path para os restantes; depois do registo, o WordPress trata ambos da mesma forma.

Os ícones personalizados funcionam na chave icon de register_block_type()?

Sim. Passa o nome registado completo, como 'myplugin/star', à chave icon de register_block_type(). O inseridor mostra o SVG personalizado em vez de um Dashicon, tanto em blocos JavaScript como em blocos apenas PHP.

wp_get_icon() devolve HTML ou uma string?

Devolve o SVG como string. Podes imprimi-la diretamente ou envolvê-la no teu próprio HTML; o segundo array $args aceita size, class, label, que define aria-label, e title.

O que devo remover de um SVG antes de o registar?

Remove cores fill e stroke fixas, os atributos width e height do <svg> de raiz, blocos <style> e scripts. Mantém o viewBox e os atributos estruturais, e usa currentColor onde o SVG precisar de uma referência de cor.

Posso registar ícones a partir de um tema?

Sim. A mesma chamada a wp_register_icon() funciona no functions.php de um tema, usando get_stylesheet_directory() para construir o caminho do ficheiro. A contrapartida é que os ícones desaparecem quando mudares de tema.

O que acontece se duas coleções tiverem um ícone com o mesmo nome?

As coleções funcionam como namespaces, pelo que myplugin/heart e otherplugin/heart coexistem sem conflito. O identificador único é sempre o nome completo, incluindo o prefixo da coleção.

O WordPress sanitiza os SVGs no registo?

Não. O WordPress não altera o conteúdo SVG quando o regista: serve a string fornecida ou o conteúdo do ficheiro indicado. Sanitiza os SVGs antes de os distribuíres, removendo scripts, referências externas e qualquer elemento desnecessário.

Aplicar o padrão no plugin

Começa por registar a coleção, escolhe content para SVGs isolados e file_path com glob() para uma biblioteca. Depois reutiliza os nomes completos no core/icon, nos templates PHP, nos shortcodes, na REST API e na chave icon dos teus blocos.

Este padrão de registar uma vez e expor em vários contextos aproxima a API de ícones da arquitetura usada por APIs fundamentais do WordPress, como Abilities e block bindings. O plugin completo com SVGs de exemplo, README e registo em lote está disponível em GitHub.

Junte-se à comunidade HelloWP!

Converse conosco sobre WordPress, desenvolvimento web e compartilhe experiências com outros desenvolvedores.

- membros
- online
Participar

Usamos cookies para melhorar a sua experiência. Ao continuar, concorda com a nossa Política de Cookies.