[{"data":1,"prerenderedAt":1042},["ShallowReactive",2],{"pt-BR-article-\u002Fblog\u002Fcomo-validar-cartao-de-credito-com-javascript":3,"pt-BR-related-posts-\u002Fblog\u002Fcomo-validar-cartao-de-credito-com-javascript":883},{"id":4,"title":5,"articleCover":6,"articleCoverEmbed":7,"articleCoverEmbedUploadDate":7,"articleCoverHeight":8,"articleCoverWidth":9,"authorId":10,"body":11,"categoriesIds":867,"description":869,"enAlternateSlug":870,"extension":871,"meta":872,"navigation":246,"path":873,"ptBrAlternateSlug":874,"publishedAt":875,"seo":876,"sitemap":877,"stem":879,"updatedAt":880,"wordCount":881,"__hash__":882},"blog\u002Fblog\u002Fcomo-validar-cartao-de-credito-com-javascript.md","Como validar um cartão de crédito com JavaScript (algoritmo de Luhn)","\u002Fimages\u002Fblog\u002Fjavascript\u002Fcomo-validar-cartao-de-credito-com-javascript.webp",null,720,1280,"thiago-nunes-batista",{"type":12,"value":13,"toc":844},"minimark",[14,18,21,26,34,37,40,44,56,59,93,98,115,142,148,151,155,158,649,668,672,683,700,706,709,713,716,720,727,731,744,748,751,755,762,771,775,779,790,794,797,801,804,808,811,815,818,822,825,829,832,840],[15,16,17],"p",{},"Você está construindo um formulário de checkout e precisa validar o campo de cartão antes de enviar os dados pro gateway de pagamento. A solução mais comum e recomendada é usar o algoritmo de Luhn para checar se o número tem o formato matemático correto.",[15,19,20],{},"Neste artigo, você vai entender exatamente como o algoritmo funciona, ver um exemplo numérico passo a passo e implementar uma função JavaScript pronta pra usar no seu projeto.",[22,23,25],"h2",{"id":24},"o-que-é-o-algoritmo-de-luhn","O que é o algoritmo de Luhn",[15,27,28,29,33],{},"O algoritmo de Luhn, também chamado de \"fórmula do módulo 10\" ou \"mod-10\", foi criado por Hans Peter Luhn em 1954 e virou padrão da indústria para validar números de cartão de crédito. Ele calcula um ",[30,31,32],"strong",{},"dígito verificador"," (o último dígito do número) que permite detectar erros de digitação, como trocar dois dígitos de lugar ou digitar um número errado.",[15,35,36],{},"A ideia é simples: o emissor do cartão (banco ou bandeira) gera o número de forma que, quando você aplica a fórmula do Luhn, o resultado seja divisível por 10. Se não for, o número tem erro de formatação.",[15,38,39],{},"Isso é feito no lado do cliente (no navegador) antes de mandar os dados pro servidor. Assim você evita enviar requisições inválidas pro gateway de pagamento e melhora a experiência do usuário com feedback imediato.",[22,41,43],{"id":42},"passo-a-passo-do-algoritmo-com-exemplo-numérico","Passo a passo do algoritmo com exemplo numérico",[15,45,46,47,50,51,55],{},"Vamos validar o número de teste da Visa que várias plataformas de pagamento usam em sandbox: ",[30,48,49],{},"4242 4242 4242 4242",". Primeiro, removemos espaços e traços, ficando com ",[52,53,54],"code",{},"4242424242424242",".",[15,57,58],{},"Agora aplicamos o algoritmo de Luhn:",[60,61,62,69,75,81,87],"ol",{},[63,64,65,68],"li",{},[30,66,67],{},"Comece pelo dígito mais à direita"," (o último 2) e vá para a esquerda. Esse primeiro dígito nunca é dobrado.",[63,70,71,74],{},[30,72,73],{},"Dobre o valor de cada segundo dígito"," a partir daí, ou seja, pule um, dobre o próximo, pule um, dobre o próximo, e assim por diante.",[63,76,77,80],{},[30,78,79],{},"Se o dobro resultar em dois dígitos",", some os dois algarismos entre si (ou subtraia 9, é equivalente).",[63,82,83,86],{},[30,84,85],{},"Some todos os dígitos"," (os dobrados\u002Fajustados e os que não foram alterados).",[63,88,89,92],{},[30,90,91],{},"Se o total for divisível por 10",", o número é válido pelo algoritmo de Luhn.",[94,95,97],"h3",{"id":96},"exemplo-prático-com-4242424242424242","Exemplo prático com 4242424242424242",[15,99,100,101,104,105,108,109,111,112,114],{},"O número tem 16 dígitos, alternando ",[52,102,103],{},"4"," e ",[52,106,107],{},"2",". Começando pelo dígito mais à direita (que não é dobrado) e indo para a esquerda, os dígitos que caem na posição \"dobrar\" são sempre os ",[52,110,103],{},", e os que caem na posição \"não dobrar\" são sempre os ",[52,113,107],{},". Isso acontece porque o número inteiro segue esse padrão alternado.",[116,117,118,127],"ul",{},[63,119,120,123,124,126],{},[30,121,122],{},"Dígitos que não são dobrados"," (8 dígitos, todos ",[52,125,107],{},"): 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 = 16",[63,128,129,123,132,134,135,137,138,141],{},[30,130,131],{},"Dígitos dobrados",[52,133,103],{},"): cada ",[52,136,103],{}," dobrado vira ",[52,139,140],{},"8"," (4 × 2 = 8, não passa de 9, não precisa ajustar). 8 + 8 + 8 + 8 + 8 + 8 + 8 + 8 = 64",[15,143,144,145,55],{},"Somando os dois grupos: 16 + 64 = ",[30,146,147],{},"80",[15,149,150],{},"Como 80 é divisível por 10 (resto 0), esse número passa na validação do algoritmo de Luhn.",[22,152,154],{"id":153},"implementação-em-javascript-puro","Implementação em JavaScript puro",[15,156,157],{},"Abaixo está uma função completa que remove espaços, traços e outros caracteres não numéricos, depois aplica o algoritmo de Luhn:",[159,160,165],"pre",{"className":161,"code":162,"language":163,"meta":164,"style":164},"language-javascript shiki shiki-themes dracula","function validarCartaoCredito(numero) {\n  \u002F\u002F Remove tudo que não for dígito\n  const digitos = numero.replace(\u002F\\D\u002Fg, \"\");\n\n  \u002F\u002F Cartões têm entre 13 e 19 dígitos (a maioria 16)\n  if (digitos.length \u003C 13 || digitos.length > 19) {\n    return false;\n  }\n\n  let soma = 0;\n  let deveDobrar = false; \u002F\u002F começa pelo último dígito (não dobra)\n\n  \u002F\u002F Percorre da direita para a esquerda\n  for (let i = digitos.length - 1; i >= 0; i--) {\n    let d = parseInt(digitos[i], 10);\n\n    if (deveDobrar) {\n      d *= 2;\n      \u002F\u002F Se resultou em dois dígitos, soma os algarismos (ou subtrai 9)\n      if (d > 9) {\n        d -= 9;\n      }\n    }\n\n    soma += d;\n    deveDobrar = !deveDobrar; \u002F\u002F alterna para o próximo dígito\n  }\n\n  return soma % 10 === 0;\n}\n\n\u002F\u002F Testando com o número de teste da Visa\nconsole.log(validarCartaoCredito(\"4242 4242 4242 4242\")); \u002F\u002F true\nconsole.log(validarCartaoCredito(\"4242424242424242\")); \u002F\u002F true\nconsole.log(validarCartaoCredito(\"1234 5678 1234 5678\")); \u002F\u002F false\n","javascript","",[52,166,167,191,198,241,248,254,283,295,301,306,322,340,345,351,392,414,419,428,442,448,464,477,483,489,494,506,523,528,533,554,560,565,571,601,624],{"__ignoreMap":164},[168,169,172,176,180,184,188],"span",{"class":170,"line":171},"line",1,[168,173,175],{"class":174},"s0Tla","function",[168,177,179],{"class":178},"sAOxA"," validarCartaoCredito",[168,181,183],{"class":182},"sCdxs","(",[168,185,187],{"class":186},"sGEwX","numero",[168,189,190],{"class":182},") {\n",[168,192,194],{"class":170,"line":193},2,[168,195,197],{"class":196},"shSDL","  \u002F\u002F Remove tudo que não for dígito\n",[168,199,201,204,207,210,213,216,218,222,226,228,231,234,238],{"class":170,"line":200},3,[168,202,203],{"class":174},"  const",[168,205,206],{"class":182}," digitos ",[168,208,209],{"class":174},"=",[168,211,212],{"class":182}," numero.",[168,214,215],{"class":178},"replace",[168,217,183],{"class":182},[168,219,221],{"class":220},"s-doY","\u002F",[168,223,225],{"class":224},"sIQBb","\\D",[168,227,221],{"class":220},[168,229,230],{"class":174},"g",[168,232,233],{"class":182},", ",[168,235,237],{"class":236},"seVfx","\"\"",[168,239,240],{"class":182},");\n",[168,242,244],{"class":170,"line":243},4,[168,245,247],{"emptyLinePlaceholder":246},true,"\n",[168,249,251],{"class":170,"line":250},5,[168,252,253],{"class":196},"  \u002F\u002F Cartões têm entre 13 e 19 dígitos (a maioria 16)\n",[168,255,257,260,263,266,269,272,275,278,281],{"class":170,"line":256},6,[168,258,259],{"class":174},"  if",[168,261,262],{"class":182}," (digitos.length ",[168,264,265],{"class":174},"\u003C",[168,267,268],{"class":224}," 13",[168,270,271],{"class":174}," ||",[168,273,274],{"class":182}," digitos.length ",[168,276,277],{"class":174},">",[168,279,280],{"class":224}," 19",[168,282,190],{"class":182},[168,284,286,289,292],{"class":170,"line":285},7,[168,287,288],{"class":174},"    return",[168,290,291],{"class":224}," false",[168,293,294],{"class":182},";\n",[168,296,298],{"class":170,"line":297},8,[168,299,300],{"class":182},"  }\n",[168,302,304],{"class":170,"line":303},9,[168,305,247],{"emptyLinePlaceholder":246},[168,307,309,312,315,317,320],{"class":170,"line":308},10,[168,310,311],{"class":174},"  let",[168,313,314],{"class":182}," soma ",[168,316,209],{"class":174},[168,318,319],{"class":224}," 0",[168,321,294],{"class":182},[168,323,325,327,330,332,334,337],{"class":170,"line":324},11,[168,326,311],{"class":174},[168,328,329],{"class":182}," deveDobrar ",[168,331,209],{"class":174},[168,333,291],{"class":224},[168,335,336],{"class":182},"; ",[168,338,339],{"class":196},"\u002F\u002F começa pelo último dígito (não dobra)\n",[168,341,343],{"class":170,"line":342},12,[168,344,247],{"emptyLinePlaceholder":246},[168,346,348],{"class":170,"line":347},13,[168,349,350],{"class":196},"  \u002F\u002F Percorre da direita para a esquerda\n",[168,352,354,357,360,363,366,368,370,373,376,379,382,384,387,390],{"class":170,"line":353},14,[168,355,356],{"class":174},"  for",[168,358,359],{"class":182}," (",[168,361,362],{"class":174},"let",[168,364,365],{"class":182}," i ",[168,367,209],{"class":174},[168,369,274],{"class":182},[168,371,372],{"class":174},"-",[168,374,375],{"class":224}," 1",[168,377,378],{"class":182},"; i ",[168,380,381],{"class":174},">=",[168,383,319],{"class":224},[168,385,386],{"class":182},"; i",[168,388,389],{"class":174},"--",[168,391,190],{"class":182},[168,393,395,398,401,403,406,409,412],{"class":170,"line":394},15,[168,396,397],{"class":174},"    let",[168,399,400],{"class":182}," d ",[168,402,209],{"class":174},[168,404,405],{"class":178}," parseInt",[168,407,408],{"class":182},"(digitos[i], ",[168,410,411],{"class":224},"10",[168,413,240],{"class":182},[168,415,417],{"class":170,"line":416},16,[168,418,247],{"emptyLinePlaceholder":246},[168,420,422,425],{"class":170,"line":421},17,[168,423,424],{"class":174},"    if",[168,426,427],{"class":182}," (deveDobrar) {\n",[168,429,431,434,437,440],{"class":170,"line":430},18,[168,432,433],{"class":182},"      d ",[168,435,436],{"class":174},"*=",[168,438,439],{"class":224}," 2",[168,441,294],{"class":182},[168,443,445],{"class":170,"line":444},19,[168,446,447],{"class":196},"      \u002F\u002F Se resultou em dois dígitos, soma os algarismos (ou subtrai 9)\n",[168,449,451,454,457,459,462],{"class":170,"line":450},20,[168,452,453],{"class":174},"      if",[168,455,456],{"class":182}," (d ",[168,458,277],{"class":174},[168,460,461],{"class":224}," 9",[168,463,190],{"class":182},[168,465,467,470,473,475],{"class":170,"line":466},21,[168,468,469],{"class":182},"        d ",[168,471,472],{"class":174},"-=",[168,474,461],{"class":224},[168,476,294],{"class":182},[168,478,480],{"class":170,"line":479},22,[168,481,482],{"class":182},"      }\n",[168,484,486],{"class":170,"line":485},23,[168,487,488],{"class":182},"    }\n",[168,490,492],{"class":170,"line":491},24,[168,493,247],{"emptyLinePlaceholder":246},[168,495,497,500,503],{"class":170,"line":496},25,[168,498,499],{"class":182},"    soma ",[168,501,502],{"class":174},"+=",[168,504,505],{"class":182}," d;\n",[168,507,509,512,514,517,520],{"class":170,"line":508},26,[168,510,511],{"class":182},"    deveDobrar ",[168,513,209],{"class":174},[168,515,516],{"class":174}," !",[168,518,519],{"class":182},"deveDobrar; ",[168,521,522],{"class":196},"\u002F\u002F alterna para o próximo dígito\n",[168,524,526],{"class":170,"line":525},27,[168,527,300],{"class":182},[168,529,531],{"class":170,"line":530},28,[168,532,247],{"emptyLinePlaceholder":246},[168,534,536,539,541,544,547,550,552],{"class":170,"line":535},29,[168,537,538],{"class":174},"  return",[168,540,314],{"class":182},[168,542,543],{"class":174},"%",[168,545,546],{"class":224}," 10",[168,548,549],{"class":174}," ===",[168,551,319],{"class":224},[168,553,294],{"class":182},[168,555,557],{"class":170,"line":556},30,[168,558,559],{"class":182},"}\n",[168,561,563],{"class":170,"line":562},31,[168,564,247],{"emptyLinePlaceholder":246},[168,566,568],{"class":170,"line":567},32,[168,569,570],{"class":196},"\u002F\u002F Testando com o número de teste da Visa\n",[168,572,574,577,580,582,585,587,590,593,595,598],{"class":170,"line":573},33,[168,575,576],{"class":182},"console.",[168,578,579],{"class":178},"log",[168,581,183],{"class":182},[168,583,584],{"class":178},"validarCartaoCredito",[168,586,183],{"class":182},[168,588,589],{"class":236},"\"",[168,591,49],{"class":592},"s-mGx",[168,594,589],{"class":236},[168,596,597],{"class":182},")); ",[168,599,600],{"class":196},"\u002F\u002F true\n",[168,602,604,606,608,610,612,614,616,618,620,622],{"class":170,"line":603},34,[168,605,576],{"class":182},[168,607,579],{"class":178},[168,609,183],{"class":182},[168,611,584],{"class":178},[168,613,183],{"class":182},[168,615,589],{"class":236},[168,617,54],{"class":592},[168,619,589],{"class":236},[168,621,597],{"class":182},[168,623,600],{"class":196},[168,625,627,629,631,633,635,637,639,642,644,646],{"class":170,"line":626},35,[168,628,576],{"class":182},[168,630,579],{"class":178},[168,632,183],{"class":182},[168,634,584],{"class":178},[168,636,183],{"class":182},[168,638,589],{"class":236},[168,640,641],{"class":592},"1234 5678 1234 5678",[168,643,589],{"class":236},[168,645,597],{"class":182},[168,647,648],{"class":196},"\u002F\u002F false\n",[15,650,651,652,655,656,659,660,667],{},"Essa função é o que você usa no ",[52,653,654],{},"onblur"," ou ",[52,657,658],{},"onsubmit"," do seu formulário. Se quiser testar online antes de integrar, temos um ",[661,662,666],"a",{"href":663,"rel":664},"https:\u002F\u002Fcodigoaoponto.com\u002Fferramentas\u002Fvalidador-de-cartao-de-credito",[665],"nofollow","validador de cartão de crédito online, gratuito"," que aplica exatamente essa lógica.",[22,669,671],{"id":670},"o-que-esse-algoritmo-não-garante","O que esse algoritmo NÃO garante",[15,673,674,675,678,679,682],{},"Aqui vai o disclaimer que muita gente pula (e depois se arrepende): ",[30,676,677],{},"o algoritmo de Luhn valida apenas o FORMATO\u002Festrutura matemática do número",". Ele ",[30,680,681],{},"NÃO"," verifica:",[116,684,685,688,691,694,697],{},[63,686,687],{},"Se o cartão existe de verdade",[63,689,690],{},"Se está ativo ou bloqueado",[63,692,693],{},"Se tem limite disponível",[63,695,696],{},"Se pertence à pessoa que está preenchendo o formulário",[63,698,699],{},"Se não é um cartão reportado como roubado\u002Ffraudado",[15,701,702,703,705],{},"Isso só o emissor do cartão (banco ou bandeira) consegue checar, via gateway de pagamento real (Stripe, Pagar.me, Mercado Pago, etc.). O Luhn é só um \"filtro de digitação\". Ele evita que você mande ",[52,704,641],{}," pro gateway e receba um erro bobo que poderia ter sido pego antes.",[15,707,708],{},"Não escreva no seu código nada que sugira que validar com Luhn significa \"cartão válido pra cobrar\", porque não é verdade.",[22,710,712],{"id":711},"erros-comuns","Erros comuns",[15,714,715],{},"Se você já implementou validação de cartão, provavelmente já viu (ou cometeu) algum desses:",[94,717,719],{"id":718},"validar-só-pela-quantidade-de-dígitos","Validar só pela quantidade de dígitos",[15,721,722,723,726],{},"Muitos formulários só checam se o número tem 16 dígitos. Isso deixa passar ",[52,724,725],{},"1111111111111111",", que tem 16 dígitos mas falha no Luhn. O inverso também acontece: American Express tem 15 dígitos, então validar só por \"tem que ter 16\" quebra o fluxo pra quem usa Amex.",[94,728,730],{"id":729},"não-remover-espaçostraços-antes-de-validar","Não remover espaços\u002Ftraços antes de validar",[15,732,733,734,655,737,739,740,743],{},"O usuário digita ",[52,735,736],{},"4242-4242-4242-4242",[52,738,49],{},". Se você não limpar isso antes de aplicar o Luhn, a validação falha mesmo com o número correto. A linha ",[52,741,742],{},"numero.replace(\u002F\\D\u002Fg, '')"," resolve isso.",[94,745,747],{"id":746},"tratar-luhn-como-verificação-antifraude","Tratar Luhn como verificação antifraude",[15,749,750],{},"Isso é clássico: o time de produto pede \"valida se o cartão é válido\" e o dev implementa Luhn achando que tá fazendo verificação de fraude. Não tá. Fraude requer análise de risco, tokenização, 3D Secure, regras do gateway. Nada disso o Luhn faz.",[94,752,754],{"id":753},"usar-números-de-teste-como-se-fossem-reais","Usar números de teste como se fossem reais",[15,756,757,758,761],{},"Os números de teste que gateways como Stripe e PayPal disponibilizam são válidos pelo Luhn, mas ",[30,759,760],{},"não são cartões reais",". Eles só funcionam em ambiente de sandbox. Nunca use em produção e nunca tente \"testar se funciona\" em gateway real. Isso é violação dos termos e pode gerar bloqueio.",[15,763,764,765,770],{},"Se precisar de dados de teste válidos pelo Luhn pra testar formulários, nosso ",[661,766,769],{"href":767,"rel":768},"https:\u002F\u002Fcodigoaoponto.com\u002Fferramentas\u002Fgerador-de-cartao-de-credito",[665],"gerador de cartão de crédito para testes"," cria números estruturalmente corretos (mas não reais) pra você usar no QA.",[22,772,774],{"id":773},"perguntas-frequentes","Perguntas frequentes",[94,776,778],{"id":777},"como-saber-se-um-número-de-cartão-é-válido","Como saber se um número de cartão é válido?",[15,780,781,782,785,786,789],{},"Depende do que você quer dizer com \"válido\". Se for ",[30,783,784],{},"formato correto",", use o algoritmo de Luhn, que é o que a maioria dos gateways espera no front-end. Se for ",[30,787,788],{},"cartão que realmente funciona",", só o gateway de pagamento (via emissor) consegue responder, depois que você tenta cobrar.",[94,791,793],{"id":792},"dá-pra-testar-um-formulário-de-pagamento-sem-usar-cartão-real","Dá pra testar um formulário de pagamento sem usar cartão real?",[15,795,796],{},"Sim. Use os números de teste que cada gateway fornece (Stripe, Pagar.me, Mercado Pago, etc.). Eles são válidos pelo Luhn e simulam cenários como \"pagamento aprovado\", \"saldo insuficiente\", \"3D Secure\", etc. Nunca use cartões reais de terceiros. Use só os de sandbox.",[94,798,800],{"id":799},"validar-cartão-de-crédito-é-a-mesma-coisa-que-verificar-se-ele-está-ativo","Validar cartão de crédito é a mesma coisa que verificar se ele está ativo?",[15,802,803],{},"Não. Validar (com Luhn) checa se o número tem a estrutura matemática correta. Verificar se está ativo, tem limite ou não tá bloqueado é papel do banco, feito via gateway, quando você tenta processar o pagamento.",[94,805,807],{"id":806},"o-que-é-o-algoritmo-de-luhn-1","O que é o algoritmo de Luhn?",[15,809,810],{},"É uma fórmula matemática (módulo 10) que calcula um dígito verificador pra detectar erros de digitação em números como cartões de crédito, IMEI de celular, etc. Foi criado em 1954 por Hans Peter Luhn e virou padrão da indústria.",[94,812,814],{"id":813},"posso-usar-o-luhn-pra-evitar-fraude","Posso usar o Luhn pra evitar fraude?",[15,816,817],{},"Não. O Luhn só pega erro de digitação. Fraude requer análise comportamental, verificação de endereço, 3D Secure, regras de risco do gateway. Nada disso o Luhn faz.",[94,819,821],{"id":820},"qual-a-diferença-entre-número-válido-pelo-luhn-e-cartão-válido-pra-cobrar","Qual a diferença entre \"número válido pelo Luhn\" e \"cartão válido pra cobrar\"?",[15,823,824],{},"\"Número válido pelo Luhn\" significa formato matemático correto. \"Cartão válido pra cobrar\" significa que o emissor confirmou que o cartão existe, tá ativo, tem limite e não tá bloqueado. Só o gateway junto com o emissor respondem a segunda pergunta.",[22,826,828],{"id":827},"fechamento","Fechamento",[15,830,831],{},"Se você tá implementando validação de cartão num formulário de checkout, o algoritmo de Luhn é o primeiro passo, e o mais importante, pra evitar erros bobos de digitação. Implemente a função acima, teste com os números de sandbox do seu gateway e lembre sempre: Luhn valida formato, não valida se o cartão funciona de verdade.",[15,833,834,835,839],{},"Quer testar sua implementação antes de subir pra produção? Experimente nosso ",[661,836,838],{"href":663,"rel":837},[665],"validador de cartão de crédito online",". Ele aplica exatamente a mesma lógica que você vai usar no código.",[841,842,843],"style",{},"html pre.shiki code .s0Tla, html code.shiki .s0Tla{--shiki-default:#FF79C6}html pre.shiki code .sAOxA, html code.shiki .sAOxA{--shiki-default:#50FA7B}html pre.shiki code .sCdxs, html code.shiki .sCdxs{--shiki-default:#F8F8F2}html pre.shiki code .sGEwX, html code.shiki .sGEwX{--shiki-default:#FFB86C;--shiki-default-font-style:italic}html pre.shiki code .shSDL, html code.shiki .shSDL{--shiki-default:#6272A4}html pre.shiki code .s-doY, html code.shiki .s-doY{--shiki-default:#FF5555}html pre.shiki code .sIQBb, html code.shiki .sIQBb{--shiki-default:#BD93F9}html pre.shiki code .seVfx, html code.shiki .seVfx{--shiki-default:#E9F284}html pre.shiki code .s-mGx, html code.shiki .s-mGx{--shiki-default:#F1FA8C}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"title":164,"searchDepth":193,"depth":193,"links":845},[846,847,850,851,852,858,866],{"id":24,"depth":193,"text":25},{"id":42,"depth":193,"text":43,"children":848},[849],{"id":96,"depth":200,"text":97},{"id":153,"depth":193,"text":154},{"id":670,"depth":193,"text":671},{"id":711,"depth":193,"text":712,"children":853},[854,855,856,857],{"id":718,"depth":200,"text":719},{"id":729,"depth":200,"text":730},{"id":746,"depth":200,"text":747},{"id":753,"depth":200,"text":754},{"id":773,"depth":193,"text":774,"children":859},[860,861,862,863,864,865],{"id":777,"depth":200,"text":778},{"id":792,"depth":200,"text":793},{"id":799,"depth":200,"text":800},{"id":806,"depth":200,"text":807},{"id":813,"depth":200,"text":814},{"id":820,"depth":200,"text":821},{"id":827,"depth":193,"text":828},[163,868],"tools","Aprenda a validar número de cartão de crédito com JavaScript usando o algoritmo de Luhn. Exemplo prático, código pronto e o que o Luhn não verifica no cartão.","how-to-validate-credit-card-with-javascript","md",{},"\u002Fblog\u002Fcomo-validar-cartao-de-credito-com-javascript","como-validar-cartao-de-credito-com-javascript","2026-09-17",{"title":5,"description":869},{"loc":873,"lastmod":878},"2026-10-04","blog\u002Fcomo-validar-cartao-de-credito-com-javascript","2026-10-06",1371,"jyozPXnuNTJeWJYhcCKCLJxDch-deDwFWJnYIyUkhyY",[884,892,901,908,916,923,931,938,946,954,961,963,969,978,985,992,999,1006,1013,1021,1028,1034],{"id":885,"path":886,"title":887,"articleCover":888,"categoriesIds":889,"publishedAt":891},"blog\u002Fblog\u002Fa-maneira-correta-de-utilizar-a-nomenclatura-bem.md","\u002Fblog\u002Fa-maneira-correta-de-utilizar-a-nomenclatura-bem","A maneira correta de utilizar a nomenclatura BEM","\u002Fimages\u002Fblog\u002Fa-maneira-correta-de-utilizar-a-nomenclatura-bem.webp",[890],"css","2024-05-05",{"id":893,"path":894,"title":895,"articleCover":896,"categoriesIds":897,"publishedAt":900},"blog\u002Fblog\u002Fcomo-adicionar-caracteres-especiais-no-i18n.md","\u002Fblog\u002Fcomo-adicionar-caracteres-especiais-no-i18n","Como Adicionar Caracteres Especiais em Traduções do i18N","\u002Fimages\u002Fblog\u002Fi18n\u002Fi18n-caracteres-especiais-no-nuxtjs-thumb.webp",[898,899],"nuxt","vuejs","2025-01-29",{"id":902,"path":903,"title":904,"articleCover":905,"categoriesIds":906,"publishedAt":907},"blog\u002Fblog\u002Fcomo-adicionar-o-google-tag-manager-no-seu-website-com-nuxt-3.md","\u002Fblog\u002Fcomo-adicionar-o-google-tag-manager-no-seu-website-com-nuxt-3","Como adicionar o Google Tag Manager no seu website com Nuxt 3","\u002Fimages\u002Fblog\u002Fcomo-adicionar-google-tag-manager-em-projeto-com-nuxt-3.webp",[898,899],"2024-08-15",{"id":909,"path":910,"title":911,"articleCover":912,"categoriesIds":913,"publishedAt":915},"blog\u002Fblog\u002Fcomo-configurar-chave-ssh-no-git-para-usar-no-github.md","\u002Fblog\u002Fcomo-configurar-chave-ssh-no-git-para-usar-no-github","Chave SSH no Git: Como Configurar chave SSH para usar no GitHub","\u002Fimages\u002Fblog\u002Fgit\u002Fcomo-criar-e-configurar-chave-ssh-no-github-thumb.webp",[914],"git","2025-02-04",{"id":917,"path":918,"title":919,"articleCover":920,"categoriesIds":921,"publishedAt":922},"blog\u002Fblog\u002Fcomo-consumir-uma-api-no-javascript-com-a-fetch-api.md","\u002Fblog\u002Fcomo-consumir-uma-api-no-javascript-com-a-fetch-api","Como consumir uma API no JavaScript com a Fetch API","\u002Fimages\u002Fblog\u002Fcomo-consumir-uma-api-no-javascript-com-a-fetch-api.webp",[163],"2024-09-05",{"id":924,"path":925,"title":926,"articleCover":927,"categoriesIds":928,"publishedAt":930},"blog\u002Fblog\u002Fcomo-criar-dados-estruturados-com-nuxtjs.md","\u002Fblog\u002Fcomo-criar-dados-estruturados-com-nuxtjs","Como Adicionar Dados Estruturados no Nuxt.JS","\u002Fimages\u002Fblog\u002Fseo\u002Fstructured-data\u002Fstructured-data-thumb-1.webp",[898,899,929],"seo","2025-01-22",{"id":932,"path":933,"title":934,"articleCover":935,"categoriesIds":936,"publishedAt":937},"blog\u002Fblog\u002Fcomo-funciona-o-sistema-de-rotas-no-nuxt.md","\u002Fblog\u002Fcomo-funciona-o-sistema-de-rotas-no-nuxt","Rotas no Nuxt: dinâmicas, aninhadas e catch-all","\u002Fimages\u002Fblog\u002Fnuxt\u002Fsistema-de-rotas-no-nuxtjs-thumb.webp",[898,899],"2025-03-12",{"id":939,"path":940,"title":941,"articleCover":942,"categoriesIds":943,"publishedAt":945},"blog\u002Fblog\u002Fcomo-lidar-com-inveja-de-outros-programadores.md","\u002Fblog\u002Fcomo-lidar-com-inveja-de-outros-programadores","Como Lidar com Inveja de Outros Programadores","\u002Fimages\u002Fblog\u002Fcarreira\u002Finveja-de-programadores-com-quem-se-destaca.webp",[944],"career","2025-08-29",{"id":947,"path":948,"title":949,"articleCover":950,"categoriesIds":951,"publishedAt":953},"blog\u002Fblog\u002Fcomo-recuperar-arquivos-perdidos-no-git-pelo-vscode.md","\u002Fblog\u002Fcomo-recuperar-arquivos-perdidos-no-git-pelo-vscode","Perdeu arquivos no Git sem commit? Veja como recuperar pelo VS Code","\u002Fimages\u002Fblog\u002Fcomo-recuperar-arquivos-perdido-no-git-pelo-vscode.webp",[914,952],"vscode","2024-05-15",{"id":955,"path":956,"title":957,"articleCover":958,"categoriesIds":959,"publishedAt":960},"blog\u002Fblog\u002Fcomo-usar-middlewares-no-nuxtjs.md","\u002Fblog\u002Fcomo-usar-middlewares-no-nuxtjs","Middlewares: O que são e como utilizar no Nuxt.JS","\u002Fimages\u002Fblog\u002Fnuxt\u002Fmiddlewares-no-front-end.webp",[898,899],"2025-01-14",{"id":4,"path":873,"title":5,"articleCover":6,"categoriesIds":962,"publishedAt":875},[163,868],{"id":964,"path":965,"title":966,"articleCover":967,"categoriesIds":968,"publishedAt":875},"blog\u002Fblog\u002Fcomo-validar-cpf-com-javascript.md","\u002Fblog\u002Fcomo-validar-cpf-com-javascript","Como validar um CPF com JavaScript","\u002Fimages\u002Fblog\u002Fjavascript\u002Fcomo-validar-cpf-com-javascript.webp",[163,868],{"id":970,"path":971,"title":972,"articleCover":973,"categoriesIds":974,"publishedAt":977},"blog\u002Fblog\u002Fcomponentes-do-figma-um-guia-para-te-ajudar-a-comecar.md","\u002Fblog\u002Fcomponentes-do-figma-um-guia-para-te-ajudar-a-comecar","Guia de Componentes no Figma para Iniciantes","\u002Fimages\u002Fblog\u002Ffigma\u002Fcomponentes-do-figma-um-guia-para-te-ajudar-a-comecar.png",[975,976],"figma","ux","2024-10-15",{"id":979,"path":980,"title":981,"articleCover":982,"categoriesIds":983,"publishedAt":984},"blog\u002Fblog\u002Fhub-de-ferramentas-gratuitas-para-desenvolvedores.md","\u002Fblog\u002Fhub-de-ferramentas-gratuitas-para-desenvolvedores","Criei um Hub de Ferramentas Web Gratuitas para Devs","\u002Fimages\u002Fblog\u002Fferramentas\u002Fhub-ferramentas-gratuitas-para-desenvolvedores.webp",[868],"2026-01-06",{"id":986,"path":987,"title":988,"articleCover":989,"categoriesIds":990,"publishedAt":991},"blog\u002Fblog\u002Fo-que-sao-diretivas-no-vue-e-como-implementa-las.md","\u002Fblog\u002Fo-que-sao-diretivas-no-vue-e-como-implementa-las","Diretivas no Vue 3: nativas e personalizadas","\u002Fimages\u002Fblog\u002Fvue\u002Fo-que-sao-diretivas-no-vue-e-como-implementa-las.webp",[899],"2025-03-21",{"id":993,"path":994,"title":995,"articleCover":996,"categoriesIds":997,"publishedAt":998},"blog\u002Fblog\u002Fog-tags-o-que-sao-e-como-adicionar-no-seu-site.md","\u002Fblog\u002Fog-tags-o-que-sao-e-como-adicionar-no-seu-site","OG Tags: O que São e Como Adicioná-las ao Seu Site","\u002Fimages\u002Fblog\u002Fseo\u002Fo-que-e-como-utilizar-as-og-tags.webp",[929],"2024-10-05",{"id":1000,"path":1001,"title":1002,"articleCover":1003,"categoriesIds":1004,"publishedAt":1005},"blog\u002Fblog\u002Fos-principais-erros-de-programadores-em-entrevistas-de-emprego.md","\u002Fblog\u002Fos-principais-erros-de-programadores-em-entrevistas-de-emprego","Os principais erros de programadores em entrevistas de emprego","\u002Fimages\u002Fblog\u002Fnao-cometa-esses-erros-na-sua-entrevista.webp",[944],"2024-09-15",{"id":1007,"path":1008,"title":1009,"articleCover":1010,"categoriesIds":1011,"publishedAt":1012},"blog\u002Fblog\u002Fqual-a-diferenca-entre-a-composition-api-e-options-api-no-vuejs.md","\u002Fblog\u002Fqual-a-diferenca-entre-a-composition-api-e-options-api-no-vuejs","Qual a diferença entre a Composition API e Options API no VueJS","\u002Fimages\u002Fblog\u002Fvue\u002Fqual-a-diferenca-entre-a-composition-api-e-options-api-no-vuejs.webp",[899],"2025-02-20",{"id":1014,"path":1015,"title":1016,"articleCover":1017,"categoriesIds":1018,"publishedAt":1020},"blog\u002Fblog\u002Fscroll-infinito-como-adicionar-ao-seu-site-e-suas-vantagens.md","\u002Fblog\u002Fscroll-infinito-como-adicionar-ao-seu-site-e-suas-vantagens","Scroll Infinito no React-Native: Guia Prático","\u002Fimages\u002Fblog\u002Freact-native\u002Fscroll-infinito-como-adicionar-ao-seu-site-e-suas-vantagens.webp",[1019],"react-native","2024-12-15",{"id":1022,"path":1023,"title":1024,"articleCover":1025,"categoriesIds":1026,"publishedAt":1027},"blog\u002Fblog\u002Fvercel-compra-nuxt-labs.md","\u002Fblog\u002Fvercel-compra-nuxt-labs","Vercel comprou a Nuxt Labs! E agora, o que muda para o Nuxt?","\u002Fimages\u002Fblog\u002Fnuxt\u002Fvercel-compra-nuxt-labs.webp",[898],"2025-07-17",{"id":1029,"path":1030,"title":1031,"articleCover":1032,"categoriesIds":1033,"publishedAt":880},"blog\u002Fblog\u002Fvue-vapor-mode-como-funciona-e-como-usar.md","\u002Fblog\u002Fvue-vapor-mode-como-funciona-e-como-usar","Vue Vapor Mode: o que é e o que muda no Vue 3.6","\u002Fimages\u002Fblog\u002Fvue\u002Fvue-vapor-mode-como-funciona-e-como-usar.webp",[899,898],{"id":1035,"path":1036,"title":1037,"articleCover":1038,"categoriesIds":1039,"publishedAt":1041},"blog\u002Fblog\u002Fweb-vitals-como-a-experiencia-do-usuario-vai-afetar-o-seo-do-seu-site.md","\u002Fblog\u002Fweb-vitals-como-a-experiencia-do-usuario-vai-afetar-o-seo-do-seu-site","Web Vitals e SEO: como a experiência do usuário afeta o seu site","\u002Fimages\u002Fblog\u002Fseo\u002Fweb-vitals\u002Fweb-vitals-como-a-experiencia-do-usuario-vai-afetar-o-seo-do-seu-site.webp",[929,1040],"web-vitals","2024-10-25",1791682332876]