Muitos freelancers e agências tratam a secção de portfólio como uma galeria: “aqui está o site de uma pizzaria, bonito, não é?”. Quem contrata não compra um site, compra a solução para um problema. Um portfólio que não mostra o problema, a decisão técnica e o resultado deixa o cliente sem a informação de que precisa para o escolher.
Porque é que o portfólio de um desenvolvedor WordPress importa
Para um desenvolvedor WordPress, o portfólio é a prova de que sabe fazer o que diz, e a forma de mostrar como pensa, algo que um CV não transmite. Há muita oferta de freelancers WordPress, por isso o que o distingue é a qualidade do que mostra, não o número de projetos.
O que procura um cliente num freelancer WordPress
- Soluções, não tecnologias: a quem contrata não interessa que use React, interessa que tenha resolvido o tipo de problema dele.
- Métricas e resultados: números concretos com fonte, não frases vagas como “melhorei o desempenho”.
- Processo de raciocínio: como chegou à solução e que alternativas pôs de lado.
Como escrever um estudo de caso para o portfólio
Em vez de uma captura e um link, descreva o processo. Um bom portfólio é uma coleção de estudos de caso, e cada um responde a três perguntas.
Desafio: o problema do cliente
Não escreva “construí um site”. Escreva o problema específico. Os exemplos seguintes são ilustrativos e não vêm de projetos reais:
- “Uma loja com 10 000 produtos demorava 8 segundos a carregar e perdia carrinhos pelo caminho.”
- “O site consumia uma largura de banda mensal enorme por causa de imagens não otimizadas.”
- “O cliente perdia conversões no telemóvel porque o site não era responsivo.”
Porque funciona: quem lê reconhece-se no problema. Se tiver um parecido, percebe logo que compreende a situação dele.
Solução: o que fez e porquê
Conte não só o que fez, mas porque escolheu essa solução e não outra:
“Em vez do WooCommerce padrão, escolhi WordPress headless com Next.js porque o cliente precisava de:
- um tempo de carregamento inferior a 1 s (Core Web Vitals),
- integração com a API externa do seu ERP,
- capacidade para crescer até 100 000 produtos.
Solução: WordPress como CMS headless, frontend em Next.js, cache Redis e CDN da Cloudflare.”
Assim percebe-se que não copia modelos, mas que decide com critério técnico. Vale a pena acrescentar também o que não escolheu e porquê: uma frase do tipo “pus de parte um plugin de cache porque o catálogo mudava de hora a hora” diz mais do que a lista de ferramentas.
Resultado: números com fonte
É a parte mais importante. Mostre o estado antes e depois e diga de onde vem cada número:
- Google Analytics: conversões, taxa de rejeição, abandono do carrinho.
- PageSpeed Insights (Core Web Vitals): LCP, INP, CLS.
- GTmetrix: tempo de carregamento.
- Logs do servidor: transferência de dados e consultas à base de dados.
Um número sem fonte não sobrevive à primeira pergunta de um cliente técnico. Se não o consegue demonstrar, não o publique.
Exemplo de estudo de caso com um cliente fictício
Projeto: loja online de um fabricante de móveis. Os números deste exemplo são inventados para ilustrar o formato e não correspondem a um projeto real.
Desafio. O cliente tinha uma loja WooCommerce com 8 000 produtos. O site carregava em 6 segundos, com três consequências:
- 45 % de abandono do carrinho,
- uma queda da conversão de 3,2 % para 1,8 % num ano,
- problemas de indexação e Core Web Vitals a vermelho.
Solução.
- Migração para WordPress headless: WordPress como CMS e Next.js como frontend.
- Otimização de imagens: AVIF, carregamento diferido e imagens responsivas.
- Estratégia de cache: Redis para os produtos e Cloudflare para os recursos estáticos.
- Otimização da base de dados: índices e consultas WP_Query.
- CDN com minificação automática de CSS e JS.
Stack: WordPress headless, Next.js, Redis, Cloudflare, API REST do WooCommerce.
Resultado (ilustrativo):
- Tempo de carregamento: de 6 s para 0,8 s.
- Conversão: de 1,8 % para 3,9 %.
- Abandono do carrinho: de 45 % para 12 %.
- Core Web Vitals: tudo a verde.
Um bom caso indica também quanto tempo durou o projeto e quem participou, porque isso dá ao cliente uma ideia de escala. Se o trabalho foi só seu, diga-o; se trabalhou com um designer e outro desenvolvedor, identifique-os pela função.
Que código mostrar no GitHub
Se procura trabalho numa software house, o portfólio tem de mostrar qualidade de código.
Como publicar código de projetos privados
Mesmo que o projeto seja privado, pode criar amostras públicas:
- Excertos de projetos: extraia as melhores partes e elimine qualquer dado do cliente.
- Contribuições open source: para o WordPress Core ou para plugins.
- Projetos pessoais: pequenas ferramentas que mostrem as suas competências.
Antes de publicar um excerto, confirme que não inclui chaves, caminhos internos nem nomes do cliente.
Hooks personalizados do WordPress
Este exemplo limita e filtra a consulta principal de uma loja:
/**
* Limitar e filtrar a consulta do catálogo do WooCommerce
*
* @param WP_Query $query
*/
add_action('pre_get_posts', function ($query) {
if (!is_admin() && $query->is_main_query() && is_shop()) {
$query->set('posts_per_page', 24);
$query->set('meta_query', [
[
'key' => '_stock_status',
'value' => 'instock',
'compare' => '=',
],
]);
}
});Mostra que conhece os hooks do WordPress, que pensa no desempenho da consulta e que documenta o código. Um pormenor que conta: não acrescente no_found_rows numa listagem com paginação, porque isso estraga o cálculo das páginas.
PHP moderno (8.1 ou superior)
class ProductCache
{
public function __construct(
private Redis $redis,
private int $ttl = 3600
) {}
public function getProductData(int $productId): ?array
{
$cacheKey = "product:{$productId}";
if ($cached = $this->redis->get($cacheKey)) {
return json_decode($cached, true);
}
$product = wc_get_product($productId);
if (!$product) {
return null;
}
$data = ['id' => $productId, 'name' => $product->get_name(), 'price' => $product->get_price()];
$this->redis->setex($cacheKey, $this->ttl, json_encode($data));
return $data;
}
}Mostra propriedades tipadas, promoção de propriedades no construtor, injeção de dependências e um padrão de cache. Guarde em cache apenas os dados de que precisa, não objetos completos do WooCommerce.
Desenvolvimento de blocos do Gutenberg
import { registerBlockType } from '@wordpress/blocks';
import { useBlockProps } from '@wordpress/block-editor';
registerBlockType('meu-prefixo/portfolio-item', {
edit: ({ attributes }) => {
const blockProps = useBlockProps();
return (
<div {...blockProps}>
<h3>{attributes.title}</h3>
<p>{attributes.description}</p>
</div>
);
},
save: () => null, // Renderização do lado do servidor
});Mostra conhecimento da API de blocos, de React dentro do WordPress e de renderização no servidor. Para ir mais longe, o guia de blocos do Gutenberg, padrões e Full Site Editing explica como estruturá-los.
Que stack vale a pena mostrar
Indispensável em 2026:
- Gutenberg (FSE): Full Site Editing e desenvolvimento de blocos.
- React e Next.js: WordPress headless.
- Composer: gestão de dependências.
- WP-CLI: automatização e deploy.
- Docker: ambiente local; há um guia de desenvolvimento WordPress com Docker.
- Git: controlo de versões, e não apenas push e pull, mas uma estratégia de branches.
Conta a seu favor: TypeScript, GraphQL, testes (PHPUnit, Jest, Cypress) e CI/CD com GitHub Actions ou GitLab CI.
O que não mostrar num portfólio de desenvolvedor
- Projetos assentes em temas prontos do ThemeForest, a não ser que os tenha personalizado a fundo. Nesse caso, mostre o que mudou.
- Código sem comentários, mesmo que lhe pareça óbvio.
- Práticas antigas, como consultas SQL diretas em vez de WP_Query.
- Valores fixos no código: mostre que usa constantes, filtros e opções.
Como montar o portfólio no WordPress com ACF
Não precisa de plugins complexos: o WordPress traz o necessário.
Como registar um custom post type para o portfólio
function meu_tema_registar_portfolio_cpt() {
register_post_type('portfolio', [
'labels' => [
'name' => 'Portfólio',
'singular_name' => 'Projeto',
],
'public' => true,
'has_archive' => true,
'supports' => ['title', 'editor', 'thumbnail', 'excerpt'],
'rewrite' => ['slug' => 'portfolio'],
'show_in_rest' => true,
]);
}
add_action('init', 'meu_tema_registar_portfolio_cpt');Campos ACF para os projetos do portfólio
acf_add_local_field_group([
'key' => 'portfolio_fields',
'title' => 'Detalhes do portfólio',
'fields' => [
['key' => 'client_name', 'name' => 'client_name', 'label' => 'Nome do cliente', 'type' => 'text'],
['key' => 'project_year', 'name' => 'project_year', 'label' => 'Ano do projeto', 'type' => 'number'],
[
'key' => 'tech_stack',
'name' => 'tech_stack',
'label' => 'Stack tecnológico',
'type' => 'checkbox',
'choices' => [
'wordpress' => 'WordPress',
'react' => 'React',
'nextjs' => 'Next.js',
'woocommerce' => 'WooCommerce',
],
],
[
'key' => 'metrics',
'name' => 'metrics',
'label' => 'Métricas (antes e depois)',
'type' => 'repeater',
'sub_fields' => [
['key' => 'metric_name', 'name' => 'metric_name', 'label' => 'Métrica', 'type' => 'text'],
['key' => 'before_value', 'name' => 'before_value', 'label' => 'Antes', 'type' => 'text'],
['key' => 'after_value', 'name' => 'after_value', 'label' => 'Depois', 'type' => 'text'],
],
],
],
'location' => [[[
'param' => 'post_type',
'operator' => '==',
'value' => 'portfolio',
]]],
]);Assim cada projeto tem os mesmos campos, e pode mostrar a comparação antes e depois com a mesma estrutura em todos os casos. Os dados que não quer que apareçam no ecrã de edição, como notas internas ou a fonte de cada métrica, guarde-os em campos meta com prefixo de underscore (_fonte_metricas): o WordPress esconde-os do painel de campos personalizados.
Modelo single-portfolio.php para cada projeto
// single-portfolio.php
get_header();
?>
<article class="portfolio-case-study">
<header>
<h1><?php the_title(); ?></h1>
<p>
<?php if ($client = get_field('client_name')) : ?>
Cliente: <?php echo esc_html($client); ?>
<?php endif; ?>
Ano: <?php echo esc_html(get_field('project_year')); ?>
</p>
</header>
<section class="solution">
<h2>Solução</h2>
<?php the_content(); ?>
</section>
<section class="results">
<h2>Resultados</h2>
<?php foreach ((array) get_field('metrics') as $metric) : ?>
<p>
<?php echo esc_html($metric['metric_name']); ?>:
<?php echo esc_html($metric['before_value']); ?> para
<?php echo esc_html($metric['after_value']); ?>
</p>
<?php endforeach; ?>
</section>
</article>
<?php get_footer();Faça sempre o escape com esc_html(): o portfólio é código seu e é avaliado como tal.
Como posicionar o portfólio no Google
O portfólio não é só para pessoas: o Google também o lê.
Marcação schema.org JSON-LD para o portfólio
function meu_tema_portfolio_schema() {
$schema = [
'@context' => 'https://schema.org',
'@type' => 'CreativeWork',
'name' => get_the_title(),
'description' => get_the_excerpt(),
'creator' => [
'@type' => 'Person',
'name' => 'O seu nome',
],
'datePublished' => get_the_date('c'),
'url' => get_permalink(),
];
if ($client = get_field('client_name')) {
$schema['sourceOrganization'] = [
'@type' => 'Organization',
'name' => $client,
];
}
return $schema;
}O nome do cliente só entra na marcação se o campo tiver valor, por isso um cliente que prefere o anonimato não aparece nem na página nem nos dados estruturados.
Como otimizar as imagens do portfólio
- Carregamento diferido (lazy loading): exceto a primeira imagem visível.
- Formatos modernos: WebP ou AVIF; o guia de otimização de imagens no WordPress explica o processo.
- Imagens responsivas: tamanhos diferentes conforme o dispositivo.
- Texto alternativo descritivo: “painel de métricas antes e depois da migração”, e não “portfolio-imagem-1”.
O que têm em comum os melhores portfólios
- Métricas concretas: não “melhorei o desempenho”, mas “o tempo de carregamento desceu de 5 s para 0,8 s”, com a fonte.
- Processo de raciocínio: como se chegou à solução e o que ficou de fora.
- Código em contexto: não apenas um link para o GitHub, mas a explicação das decisões.
- Material visual: diagramas de arquitetura e capturas do antes e do depois.
- Opiniões de clientes: uma frase assinada pelo cliente, com a sua autorização, pesa mais do que qualquer adjetivo seu.
Como mostrar projetos privados ou com acordo de confidencialidade
Muitos dos melhores projetos não se podem mostrar tal como estão: o código pertence ao cliente ou o contrato impede que o nomeie. O estudo de caso continua a ser possível.
- Nome do cliente: o campo do ACF é opcional, e a marcação CreativeWork só acrescenta a organização quando tem valor. Descreva o setor, por exemplo “fabricante de móveis”, e deixe o nome vazio.
- Código: extraia excertos para um repositório público. Um hook que otimiza a WP_Query ou uma classe de cache com PHP 8.1 demonstram critério sem expor o projeto.
- Métricas: se não as registou durante o trabalho, recupere-as no Google Analytics, no PageSpeed Insights, no GTmetrix ou nos logs. Se não houver um dado fiável, descreva o desafio e a decisão técnica e não publique um número que não conseguiria defender perante o cliente.
- Autorização: pergunte o que pode publicar antes de redigir o caso, não depois.
- Arquivo próprio: guarde nos seus ficheiros os números de antes e depois, as capturas e a opinião do cliente de cada projeto, para os poder demonstrar quando alguém os puser em causa.
Um caso sem logótipo, com o problema, a solução e o porquê bem explicados, continua a responder à pergunta que conta: porque é que o cliente o deve escolher a si.
Perfil no WordPress.org como prova pública de contribuição
Um estudo de caso é escrito por si. O perfil no WordPress.org (profiles.wordpress.org) é gerado pela própria plataforma, e por isso um cliente técnico lê-o como um registo independente. Coloque um link para ele no portfólio, ao lado do perfil no GitHub.
O que mais pesa nesse perfil são os badges. O manual da equipa Meta distingue dois tipos: os badges de contribuidor, atribuídos em geral a quem contribuiu para uma equipa, e os badges de equipa, que recebem os membros ativos dessa equipa. Cada equipa define os seus próprios critérios, e vários são atribuídos automaticamente:
| Badge | Como se obtém, segundo o manual da Meta |
|---|---|
| Core Contributor | Automaticamente, embora não de imediato, ao receber props num commit do core |
| Plugin Developer | Automaticamente, ao ter um plugin no diretório |
| Theme Developer | Automaticamente, ao ter um tema no diretório |
| WordCamp Speaker | Automaticamente, pelo estatuto de orador no WordCamp.org, com utilizador do WordPress.org |
Os restantes são atribuídos manualmente por cada equipa. Os critérios variam: o manual da equipa do Openverse, por exemplo, exige cumprir pelo menos uma de várias condições, entre elas abrir cinco ou mais issues válidos, conseguir que seja integrado um pull request substancial ou traduzir 25 strings. Um badge de Plugin Developer não diz se o plugin é bom, mas diz que passou por uma revisão alheia, e isso é mais do que uma captura demonstra.
O que é o Five for the Future e como conta num portfólio
O Five for the Future nasceu de um artigo de Matt Mullenweg de 30 de setembro de 2014. A frase que dá nome ao programa diz que as organizações que querem fazer crescer o bolo do WordPress, e não apenas a sua fatia, «deveriam dedicar 5 % das suas pessoas a trabalhar em algo relacionado com o core», seja desenvolvimento, documentação, segurança, fóruns de suporte, revisão de temas, formação, testes ou tradução (Matt Mullenweg, Five for the Future, tradução própria).
Hoje o programa está em wordpress.org/five-for-the-future. Podem comprometer-se tanto organizações como pessoas: as organizações aparecem na página de compromissos (pledges), e os contribuidores individuais surgem com o nome, uma fotografia, uma breve biografia e a organização que os patrocina, se existir. Para um freelancer, um compromisso de horas semanais com uma equipa concreta (Core, Polyglots, Training, Documentation) é uma linha verificável no portfólio. Para uma agência, aparecer na lista de organizações é uma forma de demonstrar que contribui para o projeto de que vive.
Como publicar um plugin no diretório do WordPress.org
Um plugin aprovado no diretório é uma amostra de código revista por terceiros e com utilizadores reais. O manual de plugins descreve o processo:
- Registar-se no WordPress.org com um email que consulte; se submeter em nome de uma empresa, use um email oficial da empresa.
- Enviar uma descrição breve e um zip completo do plugin, o mesmo que instalaria manualmente a partir do painel.
- Aguardar a revisão: a equipa revê o código num prazo de 14 dias úteis e, se encontrar problemas, entra em contacto consigo.
- Depois da aprovação recebe acesso a um repositório Subversion; o plugin aparece no diretório quando envia o código e o readme por SVN.
Para o portfólio importam dois pormenores. O URL do plugin não pode ser alterado depois da submissão, embora o nome visível possa. E cada plugin do diretório tem um fórum de suporte próprio, por isso as suas respostas aos utilizadores ficam públicas e fazem parte do que um cliente pode ler sobre si.
As diretrizes detalhadas do diretório são 18. As que explicam mais rejeições: licença GPL ou compatível (diretriz 1), código maioritariamente legível por humanos (4), nenhuma funcionalidade bloqueada até ao pagamento (5), nenhum contacto com servidores externos sem consentimento explícito (7) e não usar marcas alheias como primeiro termo do slug (17). Se o seu plugin as cumpre, já tem um argumento técnico para o estudo de caso.
Perfil no GitHub: README de perfil e repositórios fixados
A documentação do GitHub define quatro condições para que um README apareça no seu perfil: um repositório com o mesmo nome do seu utilizador, público, com um ficheiro README.md na raiz e com algum conteúdo. Use-o como índice: o que faz, link para o portfólio, link para o perfil no WordPress.org e os dois ou três repositórios que melhor o representam.
Pode ainda fixar no perfil até seis repositórios e gists no total. Fixe os que correspondem aos seus estudos de caso, como o plugin do diretório, o repositório de excertos de clientes anonimizados ou o tema de blocos, e não os forks sem alterações.
Learn WordPress para preencher lacunas no stack
Se, ao preparar o portfólio, notar que lhe falta algo da lista de stack, o Learn WordPress organiza o conteúdo em três percursos (usar, desenvolver e desenhar com WordPress), com cursos, lições e workshops em direto. Em outubro de 2026, o curso Beginner WordPress Developer aparece com 9 horas e 59 lições, e o Intermediate Theme Developer com 8 horas e 32 lições. Um curso concluído não substitui um estudo de caso; o que entra no portfólio é o bloco ou o tema que construir com o que aprendeu.
Por onde começar a criar o seu portfólio
- Escolha 5 a 7 projetos com um resultado que consiga medir.
- Reúna os dados: métricas com fonte, capturas e, se o cliente o permitir, uma frase dele.
- Escreva o primeiro caso com a estrutura desafio, solução e resultado. Conte com cerca de duas horas.
- Prepare as amostras de código no GitHub, sem dados do cliente e com PHP 8.1 ou superior.
- Monte o CPT com ACF e publique os casos com o mesmo formato.
- Reveja o código no GitHub sempre que acrescentar um projeto: um repositório com sintaxe antiga enfraquece o caso que aponta para ele.
O portfólio não é um CV: cada projeto deve responder à pergunta de porque é que o devem escolher a si. Como referência de um caso publicado com esta estrutura, veja o estudo de caso de otimização WooCommerce.







