[{"data":1,"prerenderedAt":1611},["ShallowReactive",2],{"en-article-\u002Fen\u002Fblog\u002Fhow-to-validate-cpf-with-javascript":3,"en-related-posts-\u002Fen\u002Fblog\u002Fhow-to-validate-cpf-with-javascript":1505},{"id":4,"title":5,"articleCover":6,"articleCoverEmbed":7,"articleCoverEmbedUploadDate":7,"articleCoverHeight":8,"articleCoverWidth":9,"authorId":10,"body":11,"categoriesIds":1490,"description":1492,"enAlternateSlug":1493,"extension":1494,"meta":1495,"navigation":285,"path":1496,"ptBrAlternateSlug":1497,"publishedAt":1498,"seo":1499,"sitemap":1500,"stem":1502,"updatedAt":1501,"wordCount":1503,"__hash__":1504},"blogEn\u002Fen\u002Fblog\u002Fhow-to-validate-cpf-with-javascript.md","How to validate a CPF with JavaScript","\u002Fimages\u002Fen\u002Fblog\u002Fjavascript\u002Fhow-to-validate-cpf-with-javascript.webp",null,720,1280,"thiago-nunes-batista",{"type":12,"value":13,"toc":1467},"minimark",[14,18,26,31,34,44,47,50,55,58,69,72,78,81,87,90,96,99,105,108,114,121,125,128,134,137,143,146,152,155,161,164,170,177,182,185,189,196,199,761,764,888,900,903,926,932,939,949,953,956,1149,1152,1156,1160,1163,1204,1211,1218,1222,1225,1232,1259,1266,1269,1273,1276,1279,1313,1316,1320,1323,1326,1330,1334,1337,1344,1347,1351,1354,1368,1371,1374,1406,1410,1413,1416,1419,1423,1432,1435,1439,1442,1445,1449,1455,1463],[15,16,17],"p",{},"The CPF (Cadastro de Pessoas Físicas) is the Brazilian individual taxpayer number, and almost every Brazilian sign-up form asks for it. Validating it on the front-end helps avoid mistakes in sign-up, checkout and login forms. On the back-end, validation is a second barrier against mistyped data and basic fraud.",[15,19,20,21,25],{},"In this article, you will understand the CPF algorithm and implement a ",[22,23,24],"strong",{},"CPF validation"," function in plain JavaScript, with no external library.",[27,28,30],"h2",{"id":29},"what-the-check-digits-are","What the check digits are",[15,32,33],{},"A CPF has 11 digits:",[35,36,37,41],"ul",{},[38,39,40],"li",{},"The first 9 are the base of the document.",[38,42,43],{},"The last 2 are the check digits.",[15,45,46],{},"These two digits are calculated from the previous ones. The idea is to catch common typing errors, like swapping or dropping a number.",[15,48,49],{},"The math check, however, does not confirm that the CPF exists, belongs to a specific person or is in good standing with the Receita Federal (Brazil's federal revenue service). It only checks whether the digits follow the CPF algorithm.",[51,52,54],"h3",{"id":53},"first-check-digit","First check digit",[15,56,57],{},"Take the CPF without formatting:",[59,60,66],"pre",{"className":61,"code":63,"language":64,"meta":65},[62],"language-text","52998224725\n","text","",[67,68,63],"code",{"__ignoreMap":65},[15,70,71],{},"The first 9 digits are:",[59,73,76],{"className":74,"code":75,"language":64,"meta":65},[62],"5 2 9 9 8 2 2 4 7\n",[67,77,75],{"__ignoreMap":65},[15,79,80],{},"Multiply each number by the weights from 10 down to 2:",[59,82,85],{"className":83,"code":84,"language":64,"meta":65},[62],"5×10 + 2×9 + 9×8 + 9×7 + 8×6 + 2×5 + 2×4 + 4×3 + 7×2\n",[67,86,84],{"__ignoreMap":65},[15,88,89],{},"The result is:",[59,91,94],{"className":92,"code":93,"language":64,"meta":65},[62],"50 + 18 + 72 + 63 + 48 + 10 + 8 + 12 + 14 = 295\n",[67,95,93],{"__ignoreMap":65},[15,97,98],{},"Now calculate the remainder of the division by 11:",[59,100,103],{"className":101,"code":102,"language":64,"meta":65},[62],"295 % 11 = 9\n",[67,104,102],{"__ignoreMap":65},[15,106,107],{},"Since the remainder is greater than 1, we do:",[59,109,112],{"className":110,"code":111,"language":64,"meta":65},[62],"11 - 9 = 2\n",[67,113,111],{"__ignoreMap":65},[15,115,116,117,120],{},"So the first check digit is ",[67,118,119],{},"2",".",[51,122,124],{"id":123},"second-check-digit","Second check digit",[15,126,127],{},"Now use the first 10 digits, including the check digit you just calculated:",[59,129,132],{"className":130,"code":131,"language":64,"meta":65},[62],"5 2 9 9 8 2 2 4 7 2\n",[67,133,131],{"__ignoreMap":65},[15,135,136],{},"Apply the weights from 11 down to 2:",[59,138,141],{"className":139,"code":140,"language":64,"meta":65},[62],"5×11 + 2×10 + 9×9 + 9×8 + 8×7 + 2×6 + 2×5 + 4×4 + 7×3 + 2×2\n",[67,142,140],{"__ignoreMap":65},[15,144,145],{},"The sum is:",[59,147,150],{"className":148,"code":149,"language":64,"meta":65},[62],"55 + 20 + 81 + 72 + 56 + 12 + 10 + 16 + 21 + 4 = 347\n",[67,151,149],{"__ignoreMap":65},[15,153,154],{},"The remainder of the division by 11 is:",[59,156,159],{"className":157,"code":158,"language":64,"meta":65},[62],"347 % 11 = 6\n",[67,160,158],{"__ignoreMap":65},[15,162,163],{},"Since the remainder is greater than 1:",[59,165,168],{"className":166,"code":167,"language":64,"meta":65},[62],"11 - 6 = 5\n",[67,169,167],{"__ignoreMap":65},[15,171,172,173,176],{},"The second check digit is ",[67,174,175],{},"5",". So the full CPF is:",[59,178,180],{"className":179,"code":63,"language":64,"meta":65},[62],[67,181,63],{"__ignoreMap":65},[15,183,184],{},"That is the CPF algorithm: calculate the first digit, add it to the sequence and calculate the second.",[27,186,188],{"id":187},"implementation-in-plain-javascript","Implementation in plain JavaScript",[15,190,191,192,195],{},"The function needs to handle formatted input, like ",[67,193,194],{},"529.982.247-25",", and also a string of digits with no punctuation.",[15,197,198],{},"One possible implementation is this:",[59,200,204],{"className":201,"code":202,"language":203,"meta":65,"style":65},"language-javascript shiki shiki-themes dracula","function validateCPF(cpf) {\n  \u002F\u002F Make sure the input is treated as text\n  cpf = String(cpf).replace(\u002F\\D\u002Fg, \"\");\n\n  \u002F\u002F A valid CPF must have exactly 11 digits\n  if (cpf.length !== 11) {\n    return false;\n  }\n\n  \u002F\u002F Reject CPFs made of the same digit\n  if (\u002F^(\\d)\\1{10}$\u002F.test(cpf)) {\n    return false;\n  }\n\n  \u002F\u002F Calculate the first check digit\n  let sum = 0;\n\n  for (let i = 0; i \u003C 9; i++) {\n    sum += Number(cpf[i]) * (10 - i);\n  }\n\n  let remainder = sum % 11;\n  const firstDigit = remainder \u003C 2 ? 0 : 11 - remainder;\n\n  \u002F\u002F The calculated first digit must match the one provided\n  if (firstDigit !== Number(cpf[9])) {\n    return false;\n  }\n\n  \u002F\u002F Calculate the second check digit\n  sum = 0;\n\n  for (let i = 0; i \u003C 10; i++) {\n    sum += Number(cpf[i]) * (11 - i);\n  }\n\n  remainder = sum % 11;\n  const secondDigit = remainder \u003C 2 ? 0 : 11 - remainder;\n\n  \u002F\u002F The calculated second digit must also match the one provided\n  return secondDigit === Number(cpf[10]);\n}\n","javascript",[67,205,206,230,237,280,287,293,310,322,328,333,339,374,383,388,393,399,415,420,455,484,489,494,513,546,551,557,578,587,592,597,603,615,620,648,670,675,680,696,724,729,735,755],{"__ignoreMap":65},[207,208,211,215,219,223,227],"span",{"class":209,"line":210},"line",1,[207,212,214],{"class":213},"s0Tla","function",[207,216,218],{"class":217},"sAOxA"," validateCPF",[207,220,222],{"class":221},"sCdxs","(",[207,224,226],{"class":225},"sGEwX","cpf",[207,228,229],{"class":221},") {\n",[207,231,233],{"class":209,"line":232},2,[207,234,236],{"class":235},"shSDL","  \u002F\u002F Make sure the input is treated as text\n",[207,238,240,243,246,249,252,255,257,261,265,267,270,273,277],{"class":209,"line":239},3,[207,241,242],{"class":221},"  cpf ",[207,244,245],{"class":213},"=",[207,247,248],{"class":217}," String",[207,250,251],{"class":221},"(cpf).",[207,253,254],{"class":217},"replace",[207,256,222],{"class":221},[207,258,260],{"class":259},"s-doY","\u002F",[207,262,264],{"class":263},"sIQBb","\\D",[207,266,260],{"class":259},[207,268,269],{"class":213},"g",[207,271,272],{"class":221},", ",[207,274,276],{"class":275},"seVfx","\"\"",[207,278,279],{"class":221},");\n",[207,281,283],{"class":209,"line":282},4,[207,284,286],{"emptyLinePlaceholder":285},true,"\n",[207,288,290],{"class":209,"line":289},5,[207,291,292],{"class":235},"  \u002F\u002F A valid CPF must have exactly 11 digits\n",[207,294,296,299,302,305,308],{"class":209,"line":295},6,[207,297,298],{"class":213},"  if",[207,300,301],{"class":221}," (cpf.length ",[207,303,304],{"class":213},"!==",[207,306,307],{"class":263}," 11",[207,309,229],{"class":221},[207,311,313,316,319],{"class":209,"line":312},7,[207,314,315],{"class":213},"    return",[207,317,318],{"class":263}," false",[207,320,321],{"class":221},";\n",[207,323,325],{"class":209,"line":324},8,[207,326,327],{"class":221},"  }\n",[207,329,331],{"class":209,"line":330},9,[207,332,286],{"emptyLinePlaceholder":285},[207,334,336],{"class":209,"line":335},10,[207,337,338],{"class":235},"  \u002F\u002F Reject CPFs made of the same digit\n",[207,340,342,344,347,349,352,355,358,361,364,366,368,371],{"class":209,"line":341},11,[207,343,298],{"class":213},[207,345,346],{"class":221}," (",[207,348,260],{"class":259},[207,350,351],{"class":213},"^",[207,353,222],{"class":354},"smvxG",[207,356,357],{"class":263},"\\d",[207,359,360],{"class":354},")",[207,362,363],{"class":213},"\\1{10}$",[207,365,260],{"class":259},[207,367,120],{"class":221},[207,369,370],{"class":217},"test",[207,372,373],{"class":221},"(cpf)) {\n",[207,375,377,379,381],{"class":209,"line":376},12,[207,378,315],{"class":213},[207,380,318],{"class":263},[207,382,321],{"class":221},[207,384,386],{"class":209,"line":385},13,[207,387,327],{"class":221},[207,389,391],{"class":209,"line":390},14,[207,392,286],{"emptyLinePlaceholder":285},[207,394,396],{"class":209,"line":395},15,[207,397,398],{"class":235},"  \u002F\u002F Calculate the first check digit\n",[207,400,402,405,408,410,413],{"class":209,"line":401},16,[207,403,404],{"class":213},"  let",[207,406,407],{"class":221}," sum ",[207,409,245],{"class":213},[207,411,412],{"class":263}," 0",[207,414,321],{"class":221},[207,416,418],{"class":209,"line":417},17,[207,419,286],{"emptyLinePlaceholder":285},[207,421,423,426,428,431,434,436,438,441,444,447,450,453],{"class":209,"line":422},18,[207,424,425],{"class":213},"  for",[207,427,346],{"class":221},[207,429,430],{"class":213},"let",[207,432,433],{"class":221}," i ",[207,435,245],{"class":213},[207,437,412],{"class":263},[207,439,440],{"class":221},"; i ",[207,442,443],{"class":213},"\u003C",[207,445,446],{"class":263}," 9",[207,448,449],{"class":221},"; i",[207,451,452],{"class":213},"++",[207,454,229],{"class":221},[207,456,458,461,464,467,470,473,475,478,481],{"class":209,"line":457},19,[207,459,460],{"class":221},"    sum ",[207,462,463],{"class":213},"+=",[207,465,466],{"class":217}," Number",[207,468,469],{"class":221},"(cpf[i]) ",[207,471,472],{"class":213},"*",[207,474,346],{"class":221},[207,476,477],{"class":263},"10",[207,479,480],{"class":213}," -",[207,482,483],{"class":221}," i);\n",[207,485,487],{"class":209,"line":486},20,[207,488,327],{"class":221},[207,490,492],{"class":209,"line":491},21,[207,493,286],{"emptyLinePlaceholder":285},[207,495,497,499,502,504,506,509,511],{"class":209,"line":496},22,[207,498,404],{"class":213},[207,500,501],{"class":221}," remainder ",[207,503,245],{"class":213},[207,505,407],{"class":221},[207,507,508],{"class":213},"%",[207,510,307],{"class":263},[207,512,321],{"class":221},[207,514,516,519,522,524,526,528,531,534,536,539,541,543],{"class":209,"line":515},23,[207,517,518],{"class":213},"  const",[207,520,521],{"class":221}," firstDigit ",[207,523,245],{"class":213},[207,525,501],{"class":221},[207,527,443],{"class":213},[207,529,530],{"class":263}," 2",[207,532,533],{"class":213}," ?",[207,535,412],{"class":263},[207,537,538],{"class":213}," :",[207,540,307],{"class":263},[207,542,480],{"class":213},[207,544,545],{"class":221}," remainder;\n",[207,547,549],{"class":209,"line":548},24,[207,550,286],{"emptyLinePlaceholder":285},[207,552,554],{"class":209,"line":553},25,[207,555,556],{"class":235},"  \u002F\u002F The calculated first digit must match the one provided\n",[207,558,560,562,565,567,569,572,575],{"class":209,"line":559},26,[207,561,298],{"class":213},[207,563,564],{"class":221}," (firstDigit ",[207,566,304],{"class":213},[207,568,466],{"class":217},[207,570,571],{"class":221},"(cpf[",[207,573,574],{"class":263},"9",[207,576,577],{"class":221},"])) {\n",[207,579,581,583,585],{"class":209,"line":580},27,[207,582,315],{"class":213},[207,584,318],{"class":263},[207,586,321],{"class":221},[207,588,590],{"class":209,"line":589},28,[207,591,327],{"class":221},[207,593,595],{"class":209,"line":594},29,[207,596,286],{"emptyLinePlaceholder":285},[207,598,600],{"class":209,"line":599},30,[207,601,602],{"class":235},"  \u002F\u002F Calculate the second check digit\n",[207,604,606,609,611,613],{"class":209,"line":605},31,[207,607,608],{"class":221},"  sum ",[207,610,245],{"class":213},[207,612,412],{"class":263},[207,614,321],{"class":221},[207,616,618],{"class":209,"line":617},32,[207,619,286],{"emptyLinePlaceholder":285},[207,621,623,625,627,629,631,633,635,637,639,642,644,646],{"class":209,"line":622},33,[207,624,425],{"class":213},[207,626,346],{"class":221},[207,628,430],{"class":213},[207,630,433],{"class":221},[207,632,245],{"class":213},[207,634,412],{"class":263},[207,636,440],{"class":221},[207,638,443],{"class":213},[207,640,641],{"class":263}," 10",[207,643,449],{"class":221},[207,645,452],{"class":213},[207,647,229],{"class":221},[207,649,651,653,655,657,659,661,663,666,668],{"class":209,"line":650},34,[207,652,460],{"class":221},[207,654,463],{"class":213},[207,656,466],{"class":217},[207,658,469],{"class":221},[207,660,472],{"class":213},[207,662,346],{"class":221},[207,664,665],{"class":263},"11",[207,667,480],{"class":213},[207,669,483],{"class":221},[207,671,673],{"class":209,"line":672},35,[207,674,327],{"class":221},[207,676,678],{"class":209,"line":677},36,[207,679,286],{"emptyLinePlaceholder":285},[207,681,683,686,688,690,692,694],{"class":209,"line":682},37,[207,684,685],{"class":221},"  remainder ",[207,687,245],{"class":213},[207,689,407],{"class":221},[207,691,508],{"class":213},[207,693,307],{"class":263},[207,695,321],{"class":221},[207,697,699,701,704,706,708,710,712,714,716,718,720,722],{"class":209,"line":698},38,[207,700,518],{"class":213},[207,702,703],{"class":221}," secondDigit ",[207,705,245],{"class":213},[207,707,501],{"class":221},[207,709,443],{"class":213},[207,711,530],{"class":263},[207,713,533],{"class":213},[207,715,412],{"class":263},[207,717,538],{"class":213},[207,719,307],{"class":263},[207,721,480],{"class":213},[207,723,545],{"class":221},[207,725,727],{"class":209,"line":726},39,[207,728,286],{"emptyLinePlaceholder":285},[207,730,732],{"class":209,"line":731},40,[207,733,734],{"class":235},"  \u002F\u002F The calculated second digit must also match the one provided\n",[207,736,738,741,743,746,748,750,752],{"class":209,"line":737},41,[207,739,740],{"class":213},"  return",[207,742,703],{"class":221},[207,744,745],{"class":213},"===",[207,747,466],{"class":217},[207,749,571],{"class":221},[207,751,477],{"class":263},[207,753,754],{"class":221},"]);\n",[207,756,758],{"class":209,"line":757},42,[207,759,760],{"class":221},"}\n",[15,762,763],{},"Usage examples:",[59,765,767],{"className":201,"code":766,"language":203,"meta":65,"style":65},"console.log(validateCPF(\"529.982.247-25\"));\n\u002F\u002F true\n\nconsole.log(validateCPF(\"52998224725\"));\n\u002F\u002F true\n\nconsole.log(validateCPF(\"529.982.247-26\"));\n\u002F\u002F false\n\nconsole.log(validateCPF(\"111.111.111-11\"));\n\u002F\u002F false\n",[67,768,769,795,800,804,825,829,833,854,859,863,884],{"__ignoreMap":65},[207,770,771,774,777,779,782,784,787,790,792],{"class":209,"line":210},[207,772,773],{"class":221},"console.",[207,775,776],{"class":217},"log",[207,778,222],{"class":221},[207,780,781],{"class":217},"validateCPF",[207,783,222],{"class":221},[207,785,786],{"class":275},"\"",[207,788,194],{"class":789},"s-mGx",[207,791,786],{"class":275},[207,793,794],{"class":221},"));\n",[207,796,797],{"class":209,"line":232},[207,798,799],{"class":235},"\u002F\u002F true\n",[207,801,802],{"class":209,"line":239},[207,803,286],{"emptyLinePlaceholder":285},[207,805,806,808,810,812,814,816,818,821,823],{"class":209,"line":282},[207,807,773],{"class":221},[207,809,776],{"class":217},[207,811,222],{"class":221},[207,813,781],{"class":217},[207,815,222],{"class":221},[207,817,786],{"class":275},[207,819,820],{"class":789},"52998224725",[207,822,786],{"class":275},[207,824,794],{"class":221},[207,826,827],{"class":209,"line":289},[207,828,799],{"class":235},[207,830,831],{"class":209,"line":295},[207,832,286],{"emptyLinePlaceholder":285},[207,834,835,837,839,841,843,845,847,850,852],{"class":209,"line":312},[207,836,773],{"class":221},[207,838,776],{"class":217},[207,840,222],{"class":221},[207,842,781],{"class":217},[207,844,222],{"class":221},[207,846,786],{"class":275},[207,848,849],{"class":789},"529.982.247-26",[207,851,786],{"class":275},[207,853,794],{"class":221},[207,855,856],{"class":209,"line":324},[207,857,858],{"class":235},"\u002F\u002F false\n",[207,860,861],{"class":209,"line":330},[207,862,286],{"emptyLinePlaceholder":285},[207,864,865,867,869,871,873,875,877,880,882],{"class":209,"line":335},[207,866,773],{"class":221},[207,868,776],{"class":217},[207,870,222],{"class":221},[207,872,781],{"class":217},[207,874,222],{"class":221},[207,876,786],{"class":275},[207,878,879],{"class":789},"111.111.111-11",[207,881,786],{"class":275},[207,883,794],{"class":221},[207,885,886],{"class":209,"line":341},[207,887,858],{"class":235},[15,889,890,891,894,895,897,898,120],{},"The ",[67,892,893],{},"replace(\u002F\\D\u002Fg, '')"," call removes everything that is not a digit. That lets the function accept both ",[67,896,194],{}," and ",[67,899,820],{},[15,901,902],{},"This is the regular expression that catches repeated digits:",[59,904,906],{"className":201,"code":905,"language":203,"meta":65,"style":65},"\u002F^(\\d)\\1{10}$\u002F;\n",[67,907,908],{"__ignoreMap":65},[207,909,910,912,914,916,918,920,922,924],{"class":209,"line":210},[207,911,260],{"class":259},[207,913,351],{"class":213},[207,915,222],{"class":354},[207,917,357],{"class":263},[207,919,360],{"class":354},[207,921,363],{"class":213},[207,923,260],{"class":259},[207,925,321],{"class":221},[15,927,928,929,931],{},"It matches an 11-character sequence made of the same digit. That keeps values like ",[67,930,879],{}," from being accepted.",[15,933,934,935,938],{},"This detail tends to catch people who have already struggled with the problem: CPFs with all digits equal pass the math, but they must be rejected explicitly. If you implement only the calculation, your code will treat ",[67,936,937],{},"11111111111"," as valid.",[15,940,941,942,120],{},"If you want to test inputs quickly without building a form, use ",[943,944,948],"a",{"href":945,"rel":946},"https:\u002F\u002Fcodigoaoponto.com\u002Fen\u002Ftools\u002Fcpf-validator",[947],"nofollow","our free online CPF validator",[51,950,952],{"id":951},"validation-in-the-form","Validation in the form",[15,954,955],{},"You can call the function on the form's submit event:",[59,957,959],{"className":201,"code":958,"language":203,"meta":65,"style":65},"const form = document.querySelector(\"#form\");\nconst cpfField = document.querySelector(\"#cpf\");\nconst message = document.querySelector(\"#message\");\n\nform.addEventListener(\"submit\", function (event) {\n  event.preventDefault();\n\n  if (!validateCPF(cpfField.value)) {\n    message.textContent = \"Enter a valid CPF.\";\n    return;\n  }\n\n  message.textContent = \"Valid CPF.\";\n});\n",[67,960,961,988,1012,1036,1040,1068,1079,1083,1097,1114,1120,1124,1128,1144],{"__ignoreMap":65},[207,962,963,966,969,971,974,977,979,981,984,986],{"class":209,"line":210},[207,964,965],{"class":213},"const",[207,967,968],{"class":221}," form ",[207,970,245],{"class":213},[207,972,973],{"class":221}," document.",[207,975,976],{"class":217},"querySelector",[207,978,222],{"class":221},[207,980,786],{"class":275},[207,982,983],{"class":789},"#form",[207,985,786],{"class":275},[207,987,279],{"class":221},[207,989,990,992,995,997,999,1001,1003,1005,1008,1010],{"class":209,"line":232},[207,991,965],{"class":213},[207,993,994],{"class":221}," cpfField ",[207,996,245],{"class":213},[207,998,973],{"class":221},[207,1000,976],{"class":217},[207,1002,222],{"class":221},[207,1004,786],{"class":275},[207,1006,1007],{"class":789},"#cpf",[207,1009,786],{"class":275},[207,1011,279],{"class":221},[207,1013,1014,1016,1019,1021,1023,1025,1027,1029,1032,1034],{"class":209,"line":239},[207,1015,965],{"class":213},[207,1017,1018],{"class":221}," message ",[207,1020,245],{"class":213},[207,1022,973],{"class":221},[207,1024,976],{"class":217},[207,1026,222],{"class":221},[207,1028,786],{"class":275},[207,1030,1031],{"class":789},"#message",[207,1033,786],{"class":275},[207,1035,279],{"class":221},[207,1037,1038],{"class":209,"line":282},[207,1039,286],{"emptyLinePlaceholder":285},[207,1041,1042,1045,1048,1050,1052,1055,1057,1059,1061,1063,1066],{"class":209,"line":289},[207,1043,1044],{"class":221},"form.",[207,1046,1047],{"class":217},"addEventListener",[207,1049,222],{"class":221},[207,1051,786],{"class":275},[207,1053,1054],{"class":789},"submit",[207,1056,786],{"class":275},[207,1058,272],{"class":221},[207,1060,214],{"class":213},[207,1062,346],{"class":221},[207,1064,1065],{"class":225},"event",[207,1067,229],{"class":221},[207,1069,1070,1073,1076],{"class":209,"line":295},[207,1071,1072],{"class":221},"  event.",[207,1074,1075],{"class":217},"preventDefault",[207,1077,1078],{"class":221},"();\n",[207,1080,1081],{"class":209,"line":312},[207,1082,286],{"emptyLinePlaceholder":285},[207,1084,1085,1087,1089,1092,1094],{"class":209,"line":324},[207,1086,298],{"class":213},[207,1088,346],{"class":221},[207,1090,1091],{"class":213},"!",[207,1093,781],{"class":217},[207,1095,1096],{"class":221},"(cpfField.value)) {\n",[207,1098,1099,1102,1104,1107,1110,1112],{"class":209,"line":330},[207,1100,1101],{"class":221},"    message.textContent ",[207,1103,245],{"class":213},[207,1105,1106],{"class":275}," \"",[207,1108,1109],{"class":789},"Enter a valid CPF.",[207,1111,786],{"class":275},[207,1113,321],{"class":221},[207,1115,1116,1118],{"class":209,"line":335},[207,1117,315],{"class":213},[207,1119,321],{"class":221},[207,1121,1122],{"class":209,"line":341},[207,1123,327],{"class":221},[207,1125,1126],{"class":209,"line":376},[207,1127,286],{"emptyLinePlaceholder":285},[207,1129,1130,1133,1135,1137,1140,1142],{"class":209,"line":385},[207,1131,1132],{"class":221},"  message.textContent ",[207,1134,245],{"class":213},[207,1136,1106],{"class":275},[207,1138,1139],{"class":789},"Valid CPF.",[207,1141,786],{"class":275},[207,1143,321],{"class":221},[207,1145,1146],{"class":209,"line":390},[207,1147,1148],{"class":221},"});\n",[15,1150,1151],{},"This validation improves the experience in the browser, but it does not replace validation on the server. Any code that runs on the front-end can be changed or skipped by the client. The back-end should repeat the validation before saving or processing the data.",[27,1153,1155],{"id":1154},"common-mistakes","Common mistakes",[51,1157,1159],{"id":1158},"validating-a-cpf-with-a-format-regex-only","Validating a CPF with a format regex only",[15,1161,1162],{},"An expression like this one:",[59,1164,1166],{"className":201,"code":1165,"language":203,"meta":65,"style":65},"\u002F^\\d{3}\\.\\d{3}\\.\\d{3}-\\d{2}$\u002F;\n",[67,1167,1168],{"__ignoreMap":65},[207,1169,1170,1172,1174,1176,1179,1182,1184,1186,1188,1190,1192,1195,1197,1200,1202],{"class":209,"line":210},[207,1171,260],{"class":259},[207,1173,351],{"class":213},[207,1175,357],{"class":263},[207,1177,1178],{"class":213},"{3}",[207,1180,1181],{"class":789},"\\.",[207,1183,357],{"class":263},[207,1185,1178],{"class":213},[207,1187,1181],{"class":789},[207,1189,357],{"class":263},[207,1191,1178],{"class":213},[207,1193,1194],{"class":789},"-",[207,1196,357],{"class":263},[207,1198,1199],{"class":213},"{2}$",[207,1201,260],{"class":259},[207,1203,321],{"class":221},[15,1205,1206,1207,1210],{},"only checks whether the text has the ",[67,1208,1209],{},"000.000.000-00"," format. It does not calculate the check digits.",[15,1212,1213,1214,1217],{},"For example, ",[67,1215,1216],{},"123.456.789-00"," can be perfectly formatted and still be an invalid CPF. A regex can help check what the input looks like, but it does not replace the CPF algorithm.",[51,1219,1221],{"id":1220},"forgetting-leading-zeros","Forgetting leading zeros",[15,1223,1224],{},"A CPF is an identifier, not a number for regular math. So treat it as a string.",[15,1226,1227,1228,1231],{},"If you convert a CPF to ",[67,1229,1230],{},"Number",", a value that starts with zero can lose that zero:",[59,1233,1235],{"className":201,"code":1234,"language":203,"meta":65,"style":65},"const cpf = Number(\"012.345.678-90\");\n",[67,1236,1237],{"__ignoreMap":65},[207,1238,1239,1241,1244,1246,1248,1250,1252,1255,1257],{"class":209,"line":210},[207,1240,965],{"class":213},[207,1242,1243],{"class":221}," cpf ",[207,1245,245],{"class":213},[207,1247,466],{"class":217},[207,1249,222],{"class":221},[207,1251,786],{"class":275},[207,1253,1254],{"class":789},"012.345.678-90",[207,1256,786],{"class":275},[207,1258,279],{"class":221},[15,1260,1261,1262,1265],{},"Also, very large numbers should not be the main representation of documents. The function in this article converts the input to text with ",[67,1263,1264],{},"String(cpf)"," and removes the formatting before calculating.",[15,1267,1268],{},"In practice, keep the value from the HTML field as a string from the start.",[51,1270,1272],{"id":1271},"not-normalizing-the-input","Not normalizing the input",[15,1274,1275],{},"If the code expects exactly 11 digits, it may reject a formatted CPF before it even runs the calculation.",[15,1277,1278],{},"This step fixes the problem:",[59,1280,1282],{"className":201,"code":1281,"language":203,"meta":65,"style":65},"cpf = String(cpf).replace(\u002F\\D\u002Fg, \"\");\n",[67,1283,1284],{"__ignoreMap":65},[207,1285,1286,1289,1291,1293,1295,1297,1299,1301,1303,1305,1307,1309,1311],{"class":209,"line":210},[207,1287,1288],{"class":221},"cpf ",[207,1290,245],{"class":213},[207,1292,248],{"class":217},[207,1294,251],{"class":221},[207,1296,254],{"class":217},[207,1298,222],{"class":221},[207,1300,260],{"class":259},[207,1302,264],{"class":263},[207,1304,260],{"class":259},[207,1306,269],{"class":213},[207,1308,272],{"class":221},[207,1310,276],{"class":275},[207,1312,279],{"class":221},[15,1314,1315],{},"It removes dots, dashes, spaces and other non-numeric characters. After that, the function checks whether exactly 11 digits are left.",[51,1317,1319],{"id":1318},"validating-only-in-the-browser","Validating only in the browser",[15,1321,1322],{},"Front-end validation is useful for instant feedback, but it is not a security layer. A user can send a request straight to the server without going through the page's JavaScript.",[15,1324,1325],{},"The same rule should exist on the back-end, preferably in a single function covered by tests.",[27,1327,1329],{"id":1328},"frequently-asked-questions","Frequently asked questions",[51,1331,1333],{"id":1332},"how-do-i-know-if-a-cpf-is-valid","How do I know if a CPF is valid?",[15,1335,1336],{},"First, remove the dots and dash and confirm that 11 digits are left. Then reject sequences with all digits equal and calculate the two check digits according to the CPF algorithm.",[15,1338,1339,1340,1343],{},"The CPF is only mathematically valid if the two calculated digits match the last two digits provided. The ",[67,1341,1342],{},"validateCPF(cpf)"," function in this article runs all of these steps.",[15,1345,1346],{},"Passing the math check says nothing about whether the document is active, in good standing or tied to a specific person.",[51,1348,1350],{"id":1349},"how-do-i-calculate-the-cpf-check-digit","How do I calculate the CPF check digit?",[15,1352,1353],{},"For the first digit, multiply the 9 base digits by the weights from 10 down to 2. Add up the results and calculate the remainder of the division by 11.",[35,1355,1356,1362],{},[38,1357,1358,1359,120],{},"If the remainder is 0 or 1, the digit is ",[67,1360,1361],{},"0",[38,1363,1364,1365,120],{},"Otherwise, the digit is ",[67,1366,1367],{},"11 - remainder",[15,1369,1370],{},"For the second digit, do the same with the first 10 digits and the weights from 11 down to 2.",[15,1372,1373],{},"In JavaScript, the core of the calculation can be written like this:",[59,1375,1377],{"className":201,"code":1376,"language":203,"meta":65,"style":65},"const digit = remainder \u003C 2 ? 0 : 11 - remainder;\n",[67,1378,1379],{"__ignoreMap":65},[207,1380,1381,1383,1386,1388,1390,1392,1394,1396,1398,1400,1402,1404],{"class":209,"line":210},[207,1382,965],{"class":213},[207,1384,1385],{"class":221}," digit ",[207,1387,245],{"class":213},[207,1389,501],{"class":221},[207,1391,443],{"class":213},[207,1393,530],{"class":263},[207,1395,533],{"class":213},[207,1397,412],{"class":263},[207,1399,538],{"class":213},[207,1401,307],{"class":263},[207,1403,480],{"class":213},[207,1405,545],{"class":221},[51,1407,1409],{"id":1408},"is-validating-a-cpf-the-same-as-checking-it-with-the-receita-federal","Is validating a CPF the same as checking it with the Receita Federal?",[15,1411,1412],{},"No. The math check runs locally: the system calculates the digits and compares the result with the CPF provided.",[15,1414,1415],{},"An official lookup is a different operation. It can check registration details and the status of the CPF in an official database, usually through an authorized service or the channels the Receita Federal provides.",[15,1417,1418],{},"So a CPF can pass the algorithm and still not be in good standing, not exist in the database you checked or not belong to the person who entered it. The JavaScript code does not confirm identity or registration status.",[51,1420,1422],{"id":1421},"can-i-generate-a-valid-cpf-for-testing","Can I generate a valid CPF for testing?",[15,1424,1425,1426,1431],{},"Yes. To test input masks, forms and APIs, you can use numbers that pass the math check without using real data. If you need valid CPF numbers just to test forms, ",[943,1427,1430],{"href":1428,"rel":1429},"https:\u002F\u002Fcodigoaoponto.com\u002Fen\u002Ftools\u002Fcpf-generator",[947],"our CPF generator"," handles that in seconds.",[15,1433,1434],{},"Use test data in a controlled way and make it clear, in your team's environment, that it is fictional. Also avoid putting real documents in public examples, test files or repositories.",[51,1436,1438],{"id":1437},"does-the-function-check-whether-the-cpf-belongs-to-the-user","Does the function check whether the CPF belongs to the user?",[15,1440,1441],{},"No. It only checks the normalized format, the number of digits, the check digit rule and the rejection of repeated sequences.",[15,1443,1444],{},"To confirm ownership, you would need a different step, with an official source or a proper verification flow. Local validation does not replace that process.",[27,1446,1448],{"id":1447},"next-steps","Next steps",[15,1450,1451,1452,1454],{},"You now have the CPF algorithm and a ",[67,1453,1342],{}," function ready to adapt to your project. Put the validation on the front-end to guide the user and repeat the rule on the back-end before storing or accepting the sign-up.",[15,1456,1457,1458,1462],{},"If you want to check values without writing code, use ",[943,1459,1461],{"href":945,"rel":1460},[947],"our online CPF checker",". After that, it is worth turning the examples in this article into automated tests that cover formatted input, invalid CPFs and documents with leading zeros.",[1464,1465,1466],"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 .smvxG, html code.shiki .smvxG{--shiki-default:#FFB86C}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);}html pre.shiki code .s-mGx, html code.shiki .s-mGx{--shiki-default:#F1FA8C}",{"title":65,"searchDepth":232,"depth":232,"links":1468},[1469,1473,1476,1482,1489],{"id":29,"depth":232,"text":30,"children":1470},[1471,1472],{"id":53,"depth":239,"text":54},{"id":123,"depth":239,"text":124},{"id":187,"depth":232,"text":188,"children":1474},[1475],{"id":951,"depth":239,"text":952},{"id":1154,"depth":232,"text":1155,"children":1477},[1478,1479,1480,1481],{"id":1158,"depth":239,"text":1159},{"id":1220,"depth":239,"text":1221},{"id":1271,"depth":239,"text":1272},{"id":1318,"depth":239,"text":1319},{"id":1328,"depth":232,"text":1329,"children":1483},[1484,1485,1486,1487,1488],{"id":1332,"depth":239,"text":1333},{"id":1349,"depth":239,"text":1350},{"id":1408,"depth":239,"text":1409},{"id":1421,"depth":239,"text":1422},{"id":1437,"depth":239,"text":1438},{"id":1447,"depth":232,"text":1448},[203,1491],"tools","Learn how to validate a CPF with plain JavaScript, calculate the check digits, handle formatting and reject invalid sequences in forms, with working code.","how-to-validate-cpf-with-javascript","md",{},"\u002Fen\u002Fblog\u002Fhow-to-validate-cpf-with-javascript","como-validar-cpf-com-javascript","2026-10-04",{"title":5,"description":1492},{"loc":1496,"lastmod":1501},"2026-10-06","en\u002Fblog\u002Fhow-to-validate-cpf-with-javascript",1253,"rl6GsOytKht8bBLg9yWipV1zFDvkHy7ruCKxlllBid0",[1506,1515,1522,1531,1538,1546,1553,1561,1568,1570,1576,1584,1591,1597,1604],{"id":1507,"path":1508,"title":1509,"articleCover":1510,"categoriesIds":1511,"publishedAt":1514},"blogEn\u002Fen\u002Fblog\u002Fcore-web-vitals-how-user-experience-affects-seo.md","\u002Fen\u002Fblog\u002Fcore-web-vitals-how-user-experience-affects-seo","Core Web Vitals and SEO: How User Experience Affects Your Site","\u002Fimages\u002Fen\u002Fblog\u002Fseo\u002Fweb-vitals\u002Fcore-web-vitals-how-user-experience-affects-seo.webp",[1512,1513],"seo","web-vitals","2024-10-25",{"id":1516,"path":1517,"title":1518,"articleCover":1519,"categoriesIds":1520,"publishedAt":1521},"blogEn\u002Fen\u002Fblog\u002Ffree-developer-tools-hub.md","\u002Fen\u002Fblog\u002Ffree-developer-tools-hub","I Built a Free Web Tools Hub for Developers","\u002Fimages\u002Fen\u002Fblog\u002Ftools\u002Ffree-developer-tools-hub.webp",[1491],"2026-01-06",{"id":1523,"path":1524,"title":1525,"articleCover":1526,"categoriesIds":1527,"publishedAt":1530},"blogEn\u002Fen\u002Fblog\u002Fhow-the-routing-system-works-in-nuxt.md","\u002Fen\u002Fblog\u002Fhow-the-routing-system-works-in-nuxt","Nuxt Routing: Dynamic, Nested and Catch-All Routes","\u002Fimages\u002Fblog\u002Fnuxt\u002Fnuxt-routing-thumb.webp",[1528,1529],"nuxt","vuejs","2025-03-12",{"id":1532,"path":1533,"title":1534,"articleCover":1535,"categoriesIds":1536,"publishedAt":1537},"blogEn\u002Fen\u002Fblog\u002Fhow-to-add-special-characters-on-i18n.md","\u002Fen\u002Fblog\u002Fhow-to-add-special-characters-on-i18n","How to Add Special Characters in i18N Translations","\u002Fimages\u002Fblog\u002Fi18n\u002Fi18n-special-characters-on-nuxtjs-thumb.webp",[1528,1529],"2025-02-02",{"id":1539,"path":1540,"title":1541,"articleCover":1542,"categoriesIds":1543,"publishedAt":1545},"blogEn\u002Fen\u002Fblog\u002Fhow-to-create-and-set-up-ssh-key-github.md","\u002Fen\u002Fblog\u002Fhow-to-create-and-set-up-ssh-key-github","SSH Key in Git: How to Set Up an SSH Key for GitHub","\u002Fimages\u002Fen\u002Fblog\u002Fgit\u002Fhow-to-create-and-set-up-ssh-key-github-thumb.webp",[1544],"git","2025-02-04",{"id":1547,"path":1548,"title":1549,"articleCover":1550,"categoriesIds":1551,"publishedAt":1552},"blogEn\u002Fen\u002Fblog\u002Fhow-to-create-structured-data-with-nuxtjs.md","\u002Fen\u002Fblog\u002Fhow-to-create-structured-data-with-nuxtjs","What is Structured Data and How to Add it in Nuxt.JS","\u002Fimages\u002Fen\u002Fblog\u002Fseo\u002Fstructured-data\u002Fstructured-data-thumb-1.webp",[1528,1529,1512],"2025-01-22",{"id":1554,"path":1555,"title":1556,"articleCover":1557,"categoriesIds":1558,"publishedAt":1560},"blogEn\u002Fen\u002Fblog\u002Fhow-to-deal-with-envy-from-other-programmers.md","\u002Fen\u002Fblog\u002Fhow-to-deal-with-envy-from-other-programmers","How to Deal with Envy from Other Programmers in Your Career","\u002Fimages\u002Fen\u002Fblog\u002Fcareer\u002Fa-nail-that-stands-out-gets-hammered.webp",[1559],"career","2025-08-29",{"id":1562,"path":1563,"title":1564,"articleCover":1565,"categoriesIds":1566,"publishedAt":1567},"blogEn\u002Fen\u002Fblog\u002Fhow-to-use-middlewares-nuxtjs.md","\u002Fen\u002Fblog\u002Fhow-to-use-middlewares-nuxtjs","Middlewares: What They Are and How to Use Them in Nuxt.JS","\u002Fimages\u002Fblog\u002Fnuxt\u002Ffront-end-middlewares-thumb.webp",[1528,1529],"2025-02-03",{"id":4,"path":1496,"title":5,"articleCover":6,"categoriesIds":1569,"publishedAt":1498},[203,1491],{"id":1571,"path":1572,"title":1573,"articleCover":1574,"categoriesIds":1575,"publishedAt":1498},"blogEn\u002Fen\u002Fblog\u002Fhow-to-validate-credit-card-with-javascript.md","\u002Fen\u002Fblog\u002Fhow-to-validate-credit-card-with-javascript","How to validate a credit card with JavaScript (Luhn algorithm)","\u002Fimages\u002Fen\u002Fblog\u002Fjavascript\u002Fhow-to-validate-credit-card-with-javascript.webp",[203,1491],{"id":1577,"path":1578,"title":1579,"articleCover":1580,"categoriesIds":1581,"publishedAt":1583},"blogEn\u002Fen\u002Fblog\u002Frecovering-lost-files-in-git-with-vscode.md","\u002Fen\u002Fblog\u002Frecovering-lost-files-in-git-with-vscode","Recover Lost Files in Git Without a Commit Using VS Code Local History","\u002Fimages\u002Fen\u002Fblog\u002Fvscode\u002Fhow-to-recover-lost-files-in-git-using-vscode.webp",[1544,1582],"vscode","2025-01-21",{"id":1585,"path":1586,"title":1587,"articleCover":1588,"categoriesIds":1589,"publishedAt":1590},"blogEn\u002Fen\u002Fblog\u002Fvercel-buys-nuxt-labs.md","\u002Fen\u002Fblog\u002Fvercel-buys-nuxt-labs","Vercel Acquired Nuxt Labs! What Does This Mean for Nuxt?","\u002Fimages\u002Fen\u002Fblog\u002Fnuxt\u002Fvercel-buys-nuxt-labs.webp",[1528],"2025-07-17",{"id":1592,"path":1593,"title":1594,"articleCover":1595,"categoriesIds":1596,"publishedAt":1501},"blogEn\u002Fen\u002Fblog\u002Fvue-vapor-mode-what-it-is-and-how-to-use-it.md","\u002Fen\u002Fblog\u002Fvue-vapor-mode-what-it-is-and-how-to-use-it","Vue Vapor Mode: what it is and what changes in Vue 3.6","\u002Fimages\u002Fen\u002Fblog\u002Fvue\u002Fvue-vapor-mode-what-it-is-and-how-to-use-it.webp",[1529,1528],{"id":1598,"path":1599,"title":1600,"articleCover":1601,"categoriesIds":1602,"publishedAt":1603},"blogEn\u002Fen\u002Fblog\u002Fwhat-are-directives-in-vue-and-how-to-implement-them.md","\u002Fen\u002Fblog\u002Fwhat-are-directives-in-vue-and-how-to-implement-them","Vue 3 Directives: Built-in and Custom","\u002Fimages\u002Fen\u002Fblog\u002Fvue\u002Fwhat-are-directives-in-vue-and-how-to-implement-them.webp",[1529],"2025-03-21",{"id":1605,"path":1606,"title":1607,"articleCover":1608,"categoriesIds":1609,"publishedAt":1610},"blogEn\u002Fen\u002Fblog\u002Fwhat-is-the-difference-between-composition-api-and-options-api-in-vuejs.md","\u002Fen\u002Fblog\u002Fwhat-is-the-difference-between-composition-api-and-options-api-in-vuejs","Composition API vs Options API in Vue.js: What's the Difference?","\u002Fimages\u002Fen\u002Fblog\u002Fvue\u002Fwhat-is-the-difference-between-composition-api-and-options-api-in-vuejs.webp",[1529],"2025-02-20",1791682335446]