[{"data":1,"prerenderedAt":9081},["ShallowReactive",2],{"posts-en":3},[4,1044,2154,2404,3677,3868,5074,6750,6848],{"id":5,"title":6,"body":7,"description":1025,"extension":1026,"meta":1027,"navigation":1039,"path":1040,"seo":1041,"stem":1042,"__hash__":1043},"en/en/blog/batch-resize-images-same-size-without-stretching.md","How to Batch Resize Images to the Same Size Without Stretching",{"type":8,"value":9,"toc":983},"minimark",[10,14,31,34,39,42,53,56,59,71,74,78,152,157,160,163,177,181,184,186,200,203,206,209,213,217,220,274,277,281,284,304,307,311,314,320,323,327,330,336,339,343,346,360,363,367,376,379,412,415,419,422,428,435,449,454,468,471,475,478,481,498,501,508,511,595,598,653,656,659,670,673,687,693,697,700,703,717,720,724,727,730,738,741,744,748,751,757,760,804,807,811,814,821,824,847,851,855,858,862,865,869,872,876,879,883,886,890,893,897,901,904,908,911,915,918,922,925,933,936,940,943,947,950,976,979],[11,12,13],"p",{},"To resize multiple images to the same dimensions without stretching, preserve each image's aspect ratio and choose one of two output methods:",[15,16,17,25],"ul",{},[18,19,20,24],"li",{},[21,22,23],"strong",{},"Cover and crop:"," Fill the entire target canvas, then crop the overflow.",[18,26,27,30],{},[21,28,29],{},"Contain and pad:"," Fit the entire image inside the target canvas, then fill the unused space with a color or transparency.",[11,32,33],{},"Stretching is the third mathematical option, but it changes the proportions of the subject. It should normally be avoided for photographs, products, logos, and artwork.",[35,36,38],"h2",{"id":37},"why-equal-dimensions-can-distort-images","Why Equal Dimensions Can Distort Images",[11,40,41],{},"Every image has an aspect ratio:",[43,44,50],"pre",{"className":45,"code":47,"language":48,"meta":49},[46],"language-text","aspect ratio = width ÷ height\n","text","",[51,52,47],"code",{"__ignoreMap":49},[11,54,55],{},"A 1600 × 900 image has a 16:9 ratio. A 1200 × 1200 target is square. The original cannot fill that square and remain completely visible without leaving empty space.",[11,57,58],{},"There are only three ways to resolve the mismatch:",[60,61,62,65,68],"ol",{},[18,63,64],{},"Crop part of the image.",[18,66,67],{},"Add padding around the image.",[18,69,70],{},"Distort the image.",[11,72,73],{},"The right batch-resize setting depends on which compromise fits the publishing context.",[35,75,77],{"id":76},"cover-contain-or-stretch","Cover, Contain, or Stretch?",[79,80,81,103],"table",{},[82,83,84],"thead",{},[85,86,87,91,94,97,100],"tr",{},[88,89,90],"th",{},"Mode",[88,92,93],{},"Fills target canvas",[88,95,96],{},"Keeps entire source",[88,98,99],{},"Preserves proportions",[88,101,102],{},"Best for",[104,105,106,123,138],"tbody",{},[85,107,108,112,115,118,120],{},[109,110,111],"td",{},"Cover / crop",[109,113,114],{},"Yes",[109,116,117],{},"No",[109,119,114],{},[109,121,122],{},"Thumbnails, cards, social covers",[85,124,125,128,131,133,135],{},[109,126,127],{},"Contain / fit",[109,129,130],{},"No, padding fills gaps",[109,132,114],{},[109,134,114],{},[109,136,137],{},"Product catalogs, logos, documents",[85,139,140,143,145,147,149],{},[109,141,142],{},"Stretch",[109,144,114],{},[109,146,114],{},[109,148,117],{},[109,150,151],{},"Rare data-processing cases",[153,154,156],"h3",{"id":155},"cover-and-crop","Cover and Crop",[11,158,159],{},"The image is scaled until the canvas is completely covered. Anything outside the target boundary is cropped.",[11,161,162],{},"Use it when:",[15,164,165,168,171,174],{},[18,166,167],{},"Every card must be edge-to-edge",[18,169,170],{},"The subject has safe space around it",[18,172,173],{},"Small variations in crop are acceptable",[18,175,176],{},"The layout depends on a consistent thumbnail ratio",[153,178,180],{"id":179},"contain-and-pad","Contain and Pad",[11,182,183],{},"The image is scaled until the whole source fits inside the canvas. The remaining area becomes a background color or transparent padding.",[11,185,162],{},[15,187,188,191,194,197],{},[18,189,190],{},"Every product must remain fully visible",[18,192,193],{},"Cropping a logo or document is unacceptable",[18,195,196],{},"A consistent background is part of the catalog design",[18,198,199],{},"Source images have many different aspect ratios",[153,201,142],{"id":202},"stretch",[11,204,205],{},"The image width and height are changed independently. A person may look unnaturally wide, a circle may become an oval, and a product's proportions may be misrepresented.",[11,207,208],{},"Use stretching only when the source geometry has no visual meaning or when distortion is explicitly required.",[35,210,212],{"id":211},"a-reliable-batch-resize-workflow","A Reliable Batch-Resize Workflow",[153,214,216],{"id":215},"step-1-choose-the-final-use-case","Step 1: Choose the Final Use Case",[11,218,219],{},"Do not start with an arbitrary dimension. Identify where the files will be used:",[79,221,222,232],{},[82,223,224],{},[85,225,226,229],{},[88,227,228],{},"Use case",[88,230,231],{},"Example target",[104,233,234,242,250,258,266],{},[85,235,236,239],{},[109,237,238],{},"Square product card",[109,240,241],{},"1200 × 1200",[85,243,244,247],{},[109,245,246],{},"Blog thumbnail",[109,248,249],{},"1200 × 675",[85,251,252,255],{},[109,253,254],{},"Portrait social post",[109,256,257],{},"1080 × 1350",[85,259,260,263],{},[109,261,262],{},"Avatar",[109,264,265],{},"800 × 800",[85,267,268,271],{},[109,269,270],{},"Email product tile",[109,272,273],{},"600 × 600",[11,275,276],{},"These are examples, not platform requirements. Check the actual layout and upload limits before processing a large folder.",[153,278,280],{"id":279},"step-2-inspect-the-source-mix","Step 2: Inspect the Source Mix",[11,282,283],{},"Look for:",[15,285,286,289,292,295,298,301],{},[18,287,288],{},"Landscape and portrait images in the same folder",[18,290,291],{},"Transparent PNG files",[18,293,294],{},"Small sources that would require upscaling",[18,296,297],{},"Subjects close to an edge",[18,299,300],{},"Existing borders or backgrounds",[18,302,303],{},"Images with text that cannot be cropped",[11,305,306],{},"A batch dominated by centered product photos is well suited to contain mode. A set of editorial photographs may work better with cover mode plus manual review.",[153,308,310],{"id":309},"step-3-pick-the-target-aspect-ratio","Step 3: Pick the Target Aspect Ratio",[11,312,313],{},"Dimensions determine both resolution and aspect ratio:",[43,315,318],{"className":316,"code":317,"language":48,"meta":49},[46],"1200 × 1200 = 1:1\n1200 × 675  = 16:9\n1200 × 800  = 3:2\n1080 × 1350 = 4:5\n",[51,319,317],{"__ignoreMap":49},[11,321,322],{},"Choose the ratio required by the component first. Then choose enough pixels for the largest intended display without exporting unnecessarily huge files.",[153,324,326],{"id":325},"step-4-choose-crop-or-padding","Step 4: Choose Crop or Padding",[11,328,329],{},"Use this decision:",[43,331,334],{"className":332,"code":333,"language":48,"meta":49},[46],"Can any edge of the source be removed safely?\n├── Yes → use cover/crop\n└── No  → use contain/padding\n",[51,335,333],{"__ignoreMap":49},[11,337,338],{},"For a transparent output, select a format that supports transparency, such as PNG or WebP. JPEG fills transparent areas with a solid background, so choose that background deliberately before export.",[153,340,342],{"id":341},"step-5-set-the-background-and-alignment","Step 5: Set the Background and Alignment",[11,344,345],{},"Contain mode needs a canvas background. Common choices include:",[15,347,348,351,354,357],{},[18,349,350],{},"White for marketplace product photos",[18,352,353],{},"A brand-neutral light gray for catalogs",[18,355,356],{},"Transparent for assets reused on different backgrounds",[18,358,359],{},"A sampled brand color for campaign graphics",[11,361,362],{},"Center alignment works for many batches, but it is not always correct. Shoes may need bottom alignment, portraits may need a higher focal point, and logos may require even optical spacing.",[153,364,366],{"id":365},"step-6-process-and-review-the-batch","Step 6: Process and Review the Batch",[11,368,369,370,375],{},"Use a batch tool to apply identical settings to every file. The ",[371,372,374],"a",{"href":373},"/blog/free-online-image-tools-blog/","vekbox Image Tools guide"," covers canvas resizing, proportional scaling, cropping, compression, and batch export in the browser.",[11,377,378],{},"A typical workflow is:",[60,380,381,391,394,397,400,403,406,409],{},[18,382,383,384,390],{},"Open ",[371,385,389],{"href":386,"rel":387},"https://imgx.vekbox.com/",[388],"nofollow","vekbox Image Tools",".",[18,392,393],{},"Add the source images or folder.",[18,395,396],{},"Enter the target width and height.",[18,398,399],{},"Select cover or contain behavior.",[18,401,402],{},"Choose a background color or transparency.",[18,404,405],{},"Select the output format.",[18,407,408],{},"Preview representative landscape, portrait, and square sources.",[18,410,411],{},"Export the batch and inspect the outliers.",[11,413,414],{},"Batch processing makes the rule consistent, but it does not remove the need for a visual check. Review files where faces, text, or products sit close to the edges.",[35,416,418],{"id":417},"worked-example-product-photos","Worked Example: Product Photos",[11,420,421],{},"Assume a storefront requires square 1200 × 1200 images. The source folder includes:",[43,423,426],{"className":424,"code":425,"language":48,"meta":49},[46],"shoe-side.jpg       1800 × 1200\nbackpack-front.jpg  1200 × 1600\nwatch-closeup.png   1400 × 1400\n",[51,427,425],{"__ignoreMap":49},[11,429,430,431,434],{},"Using ",[21,432,433],{},"contain",":",[15,436,437,440,443,446],{},[18,438,439],{},"The shoe receives padding above and below.",[18,441,442],{},"The backpack receives padding on the left and right.",[18,444,445],{},"The watch nearly fills the square.",[18,447,448],{},"Every product remains visible and keeps its proportions.",[11,450,430,451,434],{},[21,452,453],{},"cover",[15,455,456,459,462,465],{},[18,457,458],{},"The shoe is cropped at the left and right.",[18,460,461],{},"The backpack is cropped at the top and bottom.",[18,463,464],{},"The watch changes very little.",[18,466,467],{},"Every tile is edge-to-edge, but some product detail may be removed.",[11,469,470],{},"For a catalog where the entire item must be visible, contain is safer. For an editorial grid that values visual impact, cover may be preferable.",[35,472,474],{"id":473},"worked-example-blog-thumbnails","Worked Example: Blog Thumbnails",[11,476,477],{},"A blog card uses a 16:9 thumbnail. Sources include screenshots, portraits, and wide diagrams.",[11,479,480],{},"A good workflow is:",[60,482,483,486,489,492,495],{},[18,484,485],{},"Use cover for photographs with enough safe space.",[18,487,488],{},"Use contain for screenshots and diagrams with important edge content.",[18,490,491],{},"Apply a consistent background to padded assets.",[18,493,494],{},"Manually crop the most important hero images.",[18,496,497],{},"Export a small set of responsive widths.",[11,499,500],{},"One batch setting may not be suitable for every content type. Splitting the folder into photo and screenshot batches usually produces better results than forcing both through the same rule.",[35,502,504,505],{"id":503},"batch-resize-vs-css-object-fit","Batch Resize vs CSS ",[51,506,507],{},"object-fit",[11,509,510],{},"CSS can make different source files look consistent in a web layout:",[43,512,516],{"className":513,"code":514,"language":515,"meta":49,"style":49},"language-css shiki shiki-themes github-light github-dark",".product-image {\n  width: 100%;\n  aspect-ratio: 1;\n  object-fit: contain;\n  background: #f8fafc;\n}\n","css",[51,517,518,531,551,564,576,589],{"__ignoreMap":49},[519,520,523,527],"span",{"class":521,"line":522},"line",1,[519,524,526],{"class":525},"sScJk",".product-image",[519,528,530],{"class":529},"sVt8B"," {\n",[519,532,534,538,541,544,548],{"class":521,"line":533},2,[519,535,537],{"class":536},"sj4cs","  width",[519,539,540],{"class":529},": ",[519,542,543],{"class":536},"100",[519,545,547],{"class":546},"szBVR","%",[519,549,550],{"class":529},";\n",[519,552,554,557,559,562],{"class":521,"line":553},3,[519,555,556],{"class":536},"  aspect-ratio",[519,558,540],{"class":529},[519,560,561],{"class":536},"1",[519,563,550],{"class":529},[519,565,567,570,572,574],{"class":521,"line":566},4,[519,568,569],{"class":536},"  object-fit",[519,571,540],{"class":529},[519,573,433],{"class":536},[519,575,550],{"class":529},[519,577,579,582,584,587],{"class":521,"line":578},5,[519,580,581],{"class":536},"  background",[519,583,540],{"class":529},[519,585,586],{"class":536},"#f8fafc",[519,588,550],{"class":529},[519,590,592],{"class":521,"line":591},6,[519,593,594],{"class":529},"}\n",[11,596,597],{},"Or crop them visually:",[43,599,601],{"className":513,"code":600,"language":515,"meta":49,"style":49},".article-thumbnail {\n  width: 100%;\n  aspect-ratio: 16 / 9;\n  object-fit: cover;\n}\n",[51,602,603,610,622,639,649],{"__ignoreMap":49},[519,604,605,608],{"class":521,"line":522},[519,606,607],{"class":525},".article-thumbnail",[519,609,530],{"class":529},[519,611,612,614,616,618,620],{"class":521,"line":533},[519,613,537],{"class":536},[519,615,540],{"class":529},[519,617,543],{"class":536},[519,619,547],{"class":546},[519,621,550],{"class":529},[519,623,624,626,628,631,634,637],{"class":521,"line":553},[519,625,556],{"class":536},[519,627,540],{"class":529},[519,629,630],{"class":536},"16",[519,632,633],{"class":529}," / ",[519,635,636],{"class":536},"9",[519,638,550],{"class":529},[519,640,641,643,645,647],{"class":521,"line":566},[519,642,569],{"class":536},[519,644,540],{"class":529},[519,646,453],{"class":536},[519,648,550],{"class":529},[519,650,651],{"class":521,"line":578},[519,652,594],{"class":529},[11,654,655],{},"This changes how the browser displays the image. It does not change the downloaded file's pixel dimensions or file size.",[11,657,658],{},"Use CSS when:",[15,660,661,664,667],{},[18,662,663],{},"The same source must appear at different ratios in different components",[18,665,666],{},"The content is managed dynamically",[18,668,669],{},"The server already creates responsive variants",[11,671,672],{},"Preprocess the actual files when:",[15,674,675,678,681,684],{},[18,676,677],{},"A marketplace requires exact upload dimensions",[18,679,680],{},"Users download or reuse the exported assets",[18,682,683],{},"Oversized originals waste storage and bandwidth",[18,685,686],{},"Every item needs a permanent background or crop",[11,688,689,690,692],{},"Many production sites use both: optimized source variants for performance and CSS ",[51,691,507],{}," for layout consistency.",[35,694,696],{"id":695},"avoid-upscaling-low-resolution-sources","Avoid Upscaling Low-Resolution Sources",[11,698,699],{},"If a 400 × 400 image is exported as 1600 × 1600, the file gains pixels but not real detail. It may look soft and can become larger without becoming better.",[11,701,702],{},"Options include:",[15,704,705,708,711,714],{},[18,706,707],{},"Choose a smaller target for the whole collection",[18,709,710],{},"Keep the small source centered with padding",[18,712,713],{},"Request a higher-resolution original",[18,715,716],{},"Separate low-resolution assets for manual treatment",[11,718,719],{},"AI upscaling can invent plausible detail, but it can also alter text, logos, textures, and product features. Review the result closely before using it for commercial or factual imagery.",[35,721,723],{"id":722},"preserve-transparency-correctly","Preserve Transparency Correctly",[11,725,726],{},"Transparent sources require an output format that supports an alpha channel.",[11,728,729],{},"Use:",[15,731,732,735],{},[18,733,734],{},"PNG for lossless transparent graphics",[18,736,737],{},"WebP for transparent images when the workflow supports it",[11,739,740],{},"If the final format is JPEG, select a background color first. Otherwise the transparent area may become black, white, or another tool-dependent default.",[11,742,743],{},"Check semi-transparent edges after conversion. Light halos can appear when an asset prepared for a white background is placed on a dark page.",[35,745,747],{"id":746},"file-naming-and-folder-structure","File Naming and Folder Structure",[11,749,750],{},"Batch tools can produce hundreds of files quickly. Use a predictable naming scheme:",[43,752,755],{"className":753,"code":754,"language":48,"meta":49},[46],"Original: backpack-front.jpg\nOutput:   backpack-front-1200x1200.webp\n",[51,756,754],{"__ignoreMap":49},[11,758,759],{},"Useful suffixes include:",[15,761,762,768,782,792],{},[18,763,764,765],{},"Dimensions: ",[51,766,767],{},"-1200x1200",[18,769,770,771,774,775,778,779],{},"Intended use: ",[51,772,773],{},"-thumbnail",", ",[51,776,777],{},"-product",", or ",[51,780,781],{},"-avatar",[18,783,784,785,788,789],{},"Density: ",[51,786,787],{},"-1x"," and ",[51,790,791],{},"-2x",[18,793,794,795,774,798,778,801],{},"Format or variant: ",[51,796,797],{},"-web",[51,799,800],{},"-mobile",[51,802,803],{},"-dark",[11,805,806],{},"Keep the original folder separate from generated output. Never overwrite the only high-quality source.",[35,808,810],{"id":809},"compress-after-resizing","Compress After Resizing",[11,812,813],{},"Once every file has the correct dimensions, perform the final format conversion and compression. This avoids spending bytes on pixels that will be discarded.",[11,815,816,817,390],{},"For a complete optimization sequence, follow the guide to ",[371,818,820],{"href":819},"/blog/compress-images-for-web-without-losing-quality/","compressing images for the web without visible quality loss",[11,822,823],{},"The final quality check should include:",[15,825,826,829,832,835,838,841,844],{},[18,827,828],{},"Correct width and height",[18,830,831],{},"No stretched subjects",[18,833,834],{},"Safe crops",[18,836,837],{},"Consistent padding",[18,839,840],{},"Correct transparency or background",[18,842,843],{},"Acceptable file size",[18,845,846],{},"Clear text and product details",[35,848,850],{"id":849},"common-batch-resize-mistakes","Common Batch-Resize Mistakes",[153,852,854],{"id":853},"forcing-width-and-height-independently","Forcing Width and Height Independently",[11,856,857],{},"This distorts the source. Lock the aspect ratio and use cover or contain.",[153,859,861],{"id":860},"cropping-every-file-from-the-center","Cropping Every File from the Center",[11,863,864],{},"Center cropping can cut off faces or objects near an edge. Review outliers or use focal-point controls when available.",[153,866,868],{"id":867},"using-white-padding-without-checking-the-page","Using White Padding Without Checking the Page",[11,870,871],{},"White borders are visible on dark or tinted layouts. Match the actual destination background or use transparency.",[153,873,875],{"id":874},"mixing-screenshots-and-photos","Mixing Screenshots and Photos",[11,877,878],{},"Screenshots often require contain mode and lossless output, while photos tolerate cropping and lossy compression. Process them as separate batches.",[153,880,882],{"id":881},"overwriting-originals","Overwriting Originals",[11,884,885],{},"Keep a master copy. Future layouts may require a different aspect ratio or a larger export.",[153,887,889],{"id":888},"assuming-identical-dimensions-mean-identical-visual-scale","Assuming Identical Dimensions Mean Identical Visual Scale",[11,891,892],{},"Two products can occupy different percentages of the canvas. Consistent dimensions do not automatically create consistent subject size. Product catalogs may need a second pass to normalize margins.",[35,894,896],{"id":895},"frequently-asked-questions","Frequently Asked Questions",[153,898,900],{"id":899},"how-do-i-make-all-images-1000-1000-without-distortion","How do I make all images 1000 × 1000 without distortion?",[11,902,903],{},"Set a 1000 × 1000 canvas and use either cover to crop the overflow or contain to add padding. Do not unlock the aspect ratio and force both dimensions.",[153,905,907],{"id":906},"should-product-images-use-crop-or-padding","Should product images use crop or padding?",[11,909,910],{},"Use padding when the entire product must remain visible. Use cropping when an edge-to-edge composition is more important and the crop cannot remove essential product information.",[153,912,914],{"id":913},"can-i-keep-a-transparent-background","Can I keep a transparent background?",[11,916,917],{},"Yes. Use contain mode with a transparent canvas and export to PNG or WebP. JPEG does not support transparency.",[153,919,921],{"id":920},"why-do-resized-images-look-blurry","Why do resized images look blurry?",[11,923,924],{},"The source may be smaller than the target, the export quality may be too low, or the browser may display the image larger than its file dimensions. Check all three.",[153,926,928,929,932],{"id":927},"is-object-fit-cover-the-same-as-cropping-the-file","Is ",[51,930,931],{},"object-fit: cover"," the same as cropping the file?",[11,934,935],{},"No. It crops only the displayed view inside the element. The browser still downloads the full source image.",[153,937,939],{"id":938},"should-every-image-on-a-website-have-the-same-dimensions","Should every image on a website have the same dimensions?",[11,941,942],{},"Only images serving the same component or content role need consistent dimensions. Hero images, article screenshots, avatars, and product tiles often require different aspect ratios.",[35,944,946],{"id":945},"final-checklist","Final Checklist",[11,948,949],{},"Before exporting a batch:",[15,951,952,955,958,961,964,967,970,973],{},[18,953,954],{},"Confirm the destination's required aspect ratio.",[18,956,957],{},"Choose cover for edge-to-edge crops or contain for full visibility.",[18,959,960],{},"Keep the aspect ratio locked.",[18,962,963],{},"Choose a deliberate background or transparency.",[18,965,966],{},"Avoid upscaling weak sources.",[18,968,969],{},"Preview portrait, landscape, and square examples.",[18,971,972],{},"Keep originals separate.",[18,974,975],{},"Compress only after the dimensions are final.",[11,977,978],{},"Consistent image dimensions are not just a file operation. The best result comes from choosing a visual rule that matches the component, applying it consistently, and reviewing the exceptions that automation cannot understand.",[980,981,982],"style",{},"html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}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 .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":49,"searchDepth":533,"depth":533,"links":984},[985,986,991,999,1000,1001,1003,1004,1005,1006,1007,1015,1024],{"id":37,"depth":533,"text":38},{"id":76,"depth":533,"text":77,"children":987},[988,989,990],{"id":155,"depth":553,"text":156},{"id":179,"depth":553,"text":180},{"id":202,"depth":553,"text":142},{"id":211,"depth":533,"text":212,"children":992},[993,994,995,996,997,998],{"id":215,"depth":553,"text":216},{"id":279,"depth":553,"text":280},{"id":309,"depth":553,"text":310},{"id":325,"depth":553,"text":326},{"id":341,"depth":553,"text":342},{"id":365,"depth":553,"text":366},{"id":417,"depth":533,"text":418},{"id":473,"depth":533,"text":474},{"id":503,"depth":533,"text":1002},"Batch Resize vs CSS object-fit",{"id":695,"depth":533,"text":696},{"id":722,"depth":533,"text":723},{"id":746,"depth":533,"text":747},{"id":809,"depth":533,"text":810},{"id":849,"depth":533,"text":850,"children":1008},[1009,1010,1011,1012,1013,1014],{"id":853,"depth":553,"text":854},{"id":860,"depth":553,"text":861},{"id":867,"depth":553,"text":868},{"id":874,"depth":553,"text":875},{"id":881,"depth":553,"text":882},{"id":888,"depth":553,"text":889},{"id":895,"depth":533,"text":896,"children":1016},[1017,1018,1019,1020,1021,1023],{"id":899,"depth":553,"text":900},{"id":906,"depth":553,"text":907},{"id":913,"depth":553,"text":914},{"id":920,"depth":553,"text":921},{"id":927,"depth":553,"text":1022},"Is object-fit: cover the same as cropping the file?",{"id":938,"depth":553,"text":939},{"id":945,"depth":533,"text":946},"Make multiple images the same width and height without distortion by choosing crop, fit, padding, and canvas settings for the whole batch.","md",{"date":1028,"updated":1028,"category":1029,"tags":1030,"order":522,"meta-description":1037,"meta-keyword":1038},"2026-07-18","Image Tools",[1031,1032,1033,1034,1035,1029,1036],"Batch Resize","Resize Images","Image Canvas","Product Photos","Aspect Ratio","Web Performance","Learn how to batch resize images to the same size without stretching. Compare cover, contain, crop, and padding workflows for consistent output.","resize multiple images to same size, batch resize images without stretching, same image dimensions, resize product photos, image canvas resize",true,"/en/blog/batch-resize-images-same-size-without-stretching",{"title":6,"description":1025},"en/blog/batch-resize-images-same-size-without-stretching","Gy3BBEjQYAcVNVYFsPvz0Z2F184YxPrda39ssQ0Wc-Y",{"id":1045,"title":1046,"body":1047,"description":2139,"extension":1026,"meta":2140,"navigation":1039,"path":2150,"seo":2151,"stem":2152,"__hash__":2153},"en/en/blog/compress-images-for-web-without-losing-quality.md","How to Compress Images for the Web Without Losing Quality",{"type":8,"value":1048,"toc":2107},[1049,1052,1059,1063,1066,1083,1086,1090,1093,1101,1104,1107,1113,1116,1119,1123,1126,1209,1213,1216,1220,1223,1227,1230,1233,1237,1247,1250,1270,1273,1290,1293,1297,1304,1307,1329,1332,1339,1343,1353,1461,1464,1470,1597,1612,1616,1626,1676,1679,1682,1722,1726,1729,1799,1806,1810,1813,1815,1845,1848,1915,1918,1922,1925,1936,1939,1956,1959,1963,1967,1970,1974,1977,1981,1984,1988,1991,1995,1998,2002,2005,2007,2011,2014,2018,2021,2025,2028,2032,2035,2039,2042,2044,2047,2078,2081,2104],[11,1050,1051],{},"To compress images for the web without an obvious loss of quality, reduce unnecessary pixel dimensions first, choose a format that matches the image, and then lower the export quality while comparing the result at its actual display size. For most photographs, WebP or a well-optimized JPEG is a practical choice. For screenshots with sharp text or images that need transparency, use PNG or lossless WebP.",[11,1053,1054,1055,1058],{},"The important word is ",[21,1056,1057],{},"obvious",". Lossy compression removes data, so it cannot be mathematically lossless. However, a carefully compressed image can look the same to a visitor while downloading much faster.",[35,1060,1062],{"id":1061},"a-practical-five-step-workflow","A Practical Five-Step Workflow",[11,1064,1065],{},"Use this sequence for each image:",[60,1067,1068,1071,1074,1077,1080],{},[18,1069,1070],{},"Find the largest size at which the image will actually appear.",[18,1072,1073],{},"Resize the source close to that display size.",[18,1075,1076],{},"Choose JPEG, PNG, or WebP based on the content.",[18,1078,1079],{},"Lower quality gradually and compare the result with the source.",[18,1081,1082],{},"Deliver responsive variants so small screens do not download the desktop file.",[11,1084,1085],{},"Compression works best when these decisions are made together. Exporting a 6000-pixel photo at a slightly lower quality is still wasteful if the page never displays it wider than 1200 pixels.",[35,1087,1089],{"id":1088},"step-1-resize-before-you-compress","Step 1: Resize Before You Compress",[11,1091,1092],{},"Pixel dimensions and compression quality solve different problems:",[15,1094,1095,1098],{},[18,1096,1097],{},"Resizing removes pixels that the layout does not need.",[18,1099,1100],{},"Compression stores the remaining pixels more efficiently.",[11,1102,1103],{},"Suppose a blog image is displayed at a maximum CSS width of 900 pixels. A 5400-pixel camera export contains six times as many pixels across, even though most visitors will never see that detail.",[11,1105,1106],{},"For a sharp result on high-density screens, exporting a version around twice the rendered CSS width is a reasonable upper bound:",[43,1108,1111],{"className":1109,"code":1110,"language":48,"meta":49},[46],"Maximum rendered width: 900 CSS pixels\nHigh-density source:     up to 1800 physical pixels\n",[51,1112,1110],{"__ignoreMap":49},[11,1114,1115],{},"This is a starting point, not a rule for every image. A detailed photograph may benefit from the larger variant, while a simple illustration may not.",[11,1117,1118],{},"Do not enlarge a small source just to reach a target number. Upscaling creates more pixels but does not restore missing detail.",[35,1120,1122],{"id":1121},"step-2-choose-the-right-image-format","Step 2: Choose the Right Image Format",[11,1124,1125],{},"No single format is best for every image.",[79,1127,1128,1141],{},[82,1129,1130],{},[85,1131,1132,1135,1138],{},[88,1133,1134],{},"Image type",[88,1136,1137],{},"Good first choice",[88,1139,1140],{},"Why",[104,1142,1143,1154,1165,1176,1187,1198],{},[85,1144,1145,1148,1151],{},[109,1146,1147],{},"Photograph",[109,1149,1150],{},"WebP or JPEG",[109,1152,1153],{},"Efficient lossy compression for continuous tones",[85,1155,1156,1159,1162],{},[109,1157,1158],{},"Product photo with transparency",[109,1160,1161],{},"WebP",[109,1163,1164],{},"Supports transparency with lossy or lossless encoding",[85,1166,1167,1170,1173],{},[109,1168,1169],{},"Screenshot with small text",[109,1171,1172],{},"PNG or lossless WebP",[109,1174,1175],{},"Preserves crisp edges and text",[85,1177,1178,1181,1184],{},[109,1179,1180],{},"Logo or simple icon",[109,1182,1183],{},"SVG",[109,1185,1186],{},"Scales cleanly without raster pixels",[85,1188,1189,1192,1195],{},[109,1190,1191],{},"Graphic with transparency",[109,1193,1194],{},"PNG or WebP",[109,1196,1197],{},"Preserves the alpha channel",[85,1199,1200,1203,1206],{},[109,1201,1202],{},"Broad compatibility fallback",[109,1204,1205],{},"JPEG or PNG",[109,1207,1208],{},"Long-standing browser support",[153,1210,1212],{"id":1211},"when-to-use-jpeg","When to Use JPEG",[11,1214,1215],{},"JPEG remains useful for photographs and broad compatibility. It does not support transparency, and strong compression can create block patterns, halos, and smearing around detailed edges.",[153,1217,1219],{"id":1218},"when-to-use-png","When to Use PNG",[11,1221,1222],{},"PNG uses lossless compression and supports transparency. It is a strong choice for screenshots, interface captures, diagrams, and graphics with limited colors. It is often unnecessarily large for photographs.",[153,1224,1226],{"id":1225},"when-to-use-webp","When to Use WebP",[11,1228,1229],{},"WebP supports photographs, transparency, and both lossy and lossless compression. It is usually a convenient web-first format when the publishing platform accepts it.",[11,1231,1232],{},"Newer formats such as AVIF can compress some images even further, but encoding speed, tooling, and visual results vary. Test the actual output instead of choosing a format only because it is newer.",[35,1234,1236],{"id":1235},"step-3-find-a-visually-lossless-quality-level","Step 3: Find a Visually Lossless Quality Level",[11,1238,1239,1240,1243,1244,1246],{},"There is no universal quality number. A setting of ",[51,1241,1242],{},"80"," in one encoder is not necessarily equivalent to ",[51,1245,1242],{}," in another.",[11,1248,1249],{},"For a photograph, a quality range around 75 to 85 is a useful place to begin. Then inspect:",[15,1251,1252,1255,1258,1261,1264,1267],{},[18,1253,1254],{},"Hair, grass, leaves, and fabric texture",[18,1256,1257],{},"Text and high-contrast edges",[18,1259,1260],{},"Smooth gradients such as skies",[18,1262,1263],{},"Skin tones",[18,1265,1266],{},"Shadows and dark areas",[18,1268,1269],{},"Transparent edges around product cutouts",[11,1271,1272],{},"Use this process:",[60,1274,1275,1278,1281,1284,1287],{},[18,1276,1277],{},"Export at the starting quality.",[18,1279,1280],{},"View the result at 100% and at the size used on the page.",[18,1282,1283],{},"Reduce quality in small steps.",[18,1285,1286],{},"Stop when artifacts become noticeable.",[18,1288,1289],{},"Return to the previous acceptable setting.",[11,1291,1292],{},"Visitors usually see the image inside a layout, not enlarged in an image editor. The in-page comparison matters most, but a 100% check helps catch damaged details before publishing.",[35,1294,1296],{"id":1295},"step-4-compress-images-in-the-browser","Step 4: Compress Images in the Browser",[11,1298,1299,1300,1303],{},"For a no-install workflow, use a browser-based batch compressor. The ",[371,1301,1302],{"href":373},"vekbox Image Tools overview"," explains the available compression, conversion, resizing, cropping, and batch export features.",[11,1305,1306],{},"A practical workflow is:",[60,1308,1309,1314,1317,1320,1323,1326],{},[18,1310,383,1311,390],{},[371,1312,389],{"href":386,"rel":1313},[388],[18,1315,1316],{},"Add the JPG, PNG, or WebP files you want to optimize.",[18,1318,1319],{},"Select the output format and a starting quality.",[18,1321,1322],{},"Compare the preview and output size.",[18,1324,1325],{},"Adjust the quality if fine details look damaged.",[18,1327,1328],{},"Export the optimized files.",[11,1330,1331],{},"Because the processing runs in the browser, the workflow is useful for quick batches and assets you do not want to upload to a remote editing service.",[11,1333,1334,1335,390],{},"If a group of images also needs consistent dimensions, resize them before the final compression pass. See ",[371,1336,1338],{"href":1337},"/blog/batch-resize-images-same-size-without-stretching/","how to batch resize images to the same size without stretching",[35,1340,1342],{"id":1341},"step-5-serve-responsive-images","Step 5: Serve Responsive Images",[11,1344,1345,1346,788,1349,1352],{},"Compressing one desktop image is not enough if every phone still downloads it. Use ",[51,1347,1348],{},"srcset",[51,1350,1351],{},"sizes"," to provide multiple widths:",[43,1354,1358],{"className":1355,"code":1356,"language":1357,"meta":49,"style":49},"language-html shiki shiki-themes github-light github-dark","\u003Cimg\n  src=\"/images/desk-1200.webp\"\n  srcset=\"\n    /images/desk-480.webp 480w,\n    /images/desk-800.webp 800w,\n    /images/desk-1200.webp 1200w\n  \"\n  sizes=\"(max-width: 768px) 100vw, 800px\"\n  width=\"1200\"\n  height=\"800\"\n  alt=\"Wooden desk with a laptop, notebook, and desk lamp\"\n>\n","html",[51,1359,1360,1369,1381,1391,1396,1401,1406,1412,1423,1433,1444,1455],{"__ignoreMap":49},[519,1361,1362,1365],{"class":521,"line":522},[519,1363,1364],{"class":529},"\u003C",[519,1366,1368],{"class":1367},"s9eBZ","img\n",[519,1370,1371,1374,1377],{"class":521,"line":533},[519,1372,1373],{"class":525},"  src",[519,1375,1376],{"class":529},"=",[519,1378,1380],{"class":1379},"sZZnC","\"/images/desk-1200.webp\"\n",[519,1382,1383,1386,1388],{"class":521,"line":553},[519,1384,1385],{"class":525},"  srcset",[519,1387,1376],{"class":529},[519,1389,1390],{"class":1379},"\"\n",[519,1392,1393],{"class":521,"line":566},[519,1394,1395],{"class":1379},"    /images/desk-480.webp 480w,\n",[519,1397,1398],{"class":521,"line":578},[519,1399,1400],{"class":1379},"    /images/desk-800.webp 800w,\n",[519,1402,1403],{"class":521,"line":591},[519,1404,1405],{"class":1379},"    /images/desk-1200.webp 1200w\n",[519,1407,1409],{"class":521,"line":1408},7,[519,1410,1411],{"class":1379},"  \"\n",[519,1413,1415,1418,1420],{"class":521,"line":1414},8,[519,1416,1417],{"class":525},"  sizes",[519,1419,1376],{"class":529},[519,1421,1422],{"class":1379},"\"(max-width: 768px) 100vw, 800px\"\n",[519,1424,1426,1428,1430],{"class":521,"line":1425},9,[519,1427,537],{"class":525},[519,1429,1376],{"class":529},[519,1431,1432],{"class":1379},"\"1200\"\n",[519,1434,1436,1439,1441],{"class":521,"line":1435},10,[519,1437,1438],{"class":525},"  height",[519,1440,1376],{"class":529},[519,1442,1443],{"class":1379},"\"800\"\n",[519,1445,1447,1450,1452],{"class":521,"line":1446},11,[519,1448,1449],{"class":525},"  alt",[519,1451,1376],{"class":529},[519,1453,1454],{"class":1379},"\"Wooden desk with a laptop, notebook, and desk lamp\"\n",[519,1456,1458],{"class":521,"line":1457},12,[519,1459,1460],{"class":529},">\n",[11,1462,1463],{},"The browser uses the viewport and device pixel density to select a suitable file.",[11,1465,1466,1467,434],{},"To provide a modern format with a fallback, use ",[51,1468,1469],{},"\u003Cpicture>",[43,1471,1473],{"className":1355,"code":1472,"language":1357,"meta":49,"style":49},"\u003Cpicture>\n  \u003Csource\n    type=\"image/webp\"\n    srcset=\"/images/product-640.webp 640w, /images/product-1280.webp 1280w\"\n  >\n  \u003Cimg\n    src=\"/images/product-1280.jpg\"\n    srcset=\"/images/product-640.jpg 640w, /images/product-1280.jpg 1280w\"\n    sizes=\"(max-width: 700px) 100vw, 700px\"\n    width=\"1280\"\n    height=\"960\"\n    alt=\"Black travel backpack shown from the front\"\n  >\n\u003C/picture>\n",[51,1474,1475,1484,1492,1502,1512,1517,1523,1533,1542,1552,1562,1572,1582,1587],{"__ignoreMap":49},[519,1476,1477,1479,1482],{"class":521,"line":522},[519,1478,1364],{"class":529},[519,1480,1481],{"class":1367},"picture",[519,1483,1460],{"class":529},[519,1485,1486,1489],{"class":521,"line":533},[519,1487,1488],{"class":529},"  \u003C",[519,1490,1491],{"class":1367},"source\n",[519,1493,1494,1497,1499],{"class":521,"line":553},[519,1495,1496],{"class":525},"    type",[519,1498,1376],{"class":529},[519,1500,1501],{"class":1379},"\"image/webp\"\n",[519,1503,1504,1507,1509],{"class":521,"line":566},[519,1505,1506],{"class":525},"    srcset",[519,1508,1376],{"class":529},[519,1510,1511],{"class":1379},"\"/images/product-640.webp 640w, /images/product-1280.webp 1280w\"\n",[519,1513,1514],{"class":521,"line":578},[519,1515,1516],{"class":529},"  >\n",[519,1518,1519,1521],{"class":521,"line":591},[519,1520,1488],{"class":529},[519,1522,1368],{"class":1367},[519,1524,1525,1528,1530],{"class":521,"line":1408},[519,1526,1527],{"class":525},"    src",[519,1529,1376],{"class":529},[519,1531,1532],{"class":1379},"\"/images/product-1280.jpg\"\n",[519,1534,1535,1537,1539],{"class":521,"line":1414},[519,1536,1506],{"class":525},[519,1538,1376],{"class":529},[519,1540,1541],{"class":1379},"\"/images/product-640.jpg 640w, /images/product-1280.jpg 1280w\"\n",[519,1543,1544,1547,1549],{"class":521,"line":1425},[519,1545,1546],{"class":525},"    sizes",[519,1548,1376],{"class":529},[519,1550,1551],{"class":1379},"\"(max-width: 700px) 100vw, 700px\"\n",[519,1553,1554,1557,1559],{"class":521,"line":1435},[519,1555,1556],{"class":525},"    width",[519,1558,1376],{"class":529},[519,1560,1561],{"class":1379},"\"1280\"\n",[519,1563,1564,1567,1569],{"class":521,"line":1446},[519,1565,1566],{"class":525},"    height",[519,1568,1376],{"class":529},[519,1570,1571],{"class":1379},"\"960\"\n",[519,1573,1574,1577,1579],{"class":521,"line":1457},[519,1575,1576],{"class":525},"    alt",[519,1578,1376],{"class":529},[519,1580,1581],{"class":1379},"\"Black travel backpack shown from the front\"\n",[519,1583,1585],{"class":521,"line":1584},13,[519,1586,1516],{"class":529},[519,1588,1590,1593,1595],{"class":521,"line":1589},14,[519,1591,1592],{"class":529},"\u003C/",[519,1594,1481],{"class":1367},[519,1596,1460],{"class":529},[11,1598,1599,1600,1603,1604,1607,1608,1611],{},"Always keep a real ",[51,1601,1602],{},"src"," on the fallback ",[51,1605,1606],{},"\u003Cimg>",". It supports browsers, tools, and crawlers that do not select a ",[51,1609,1610],{},"\u003Csource>"," candidate.",[35,1613,1615],{"id":1614},"prevent-layout-shift","Prevent Layout Shift",[11,1617,1618,1619,788,1622,1625],{},"Specify ",[51,1620,1621],{},"width",[51,1623,1624],{},"height"," attributes:",[43,1627,1629],{"className":1355,"code":1628,"language":1357,"meta":49,"style":49},"\u003Cimg\n  src=\"/images/article-cover.webp\"\n  width=\"1200\"\n  height=\"675\"\n  alt=\"Dashboard showing an image optimization report\"\n>\n",[51,1630,1631,1637,1646,1654,1663,1672],{"__ignoreMap":49},[519,1632,1633,1635],{"class":521,"line":522},[519,1634,1364],{"class":529},[519,1636,1368],{"class":1367},[519,1638,1639,1641,1643],{"class":521,"line":533},[519,1640,1373],{"class":525},[519,1642,1376],{"class":529},[519,1644,1645],{"class":1379},"\"/images/article-cover.webp\"\n",[519,1647,1648,1650,1652],{"class":521,"line":553},[519,1649,537],{"class":525},[519,1651,1376],{"class":529},[519,1653,1432],{"class":1379},[519,1655,1656,1658,1660],{"class":521,"line":566},[519,1657,1438],{"class":525},[519,1659,1376],{"class":529},[519,1661,1662],{"class":1379},"\"675\"\n",[519,1664,1665,1667,1669],{"class":521,"line":578},[519,1666,1449],{"class":525},[519,1668,1376],{"class":529},[519,1670,1671],{"class":1379},"\"Dashboard showing an image optimization report\"\n",[519,1673,1674],{"class":521,"line":591},[519,1675,1460],{"class":529},[11,1677,1678],{},"These attributes tell the browser the intrinsic aspect ratio before the file finishes loading. The browser can reserve space, reducing layout movement.",[11,1680,1681],{},"CSS can still make the image responsive:",[43,1683,1685],{"className":513,"code":1684,"language":515,"meta":49,"style":49},"img {\n  max-width: 100%;\n  height: auto;\n}\n",[51,1686,1687,1694,1707,1718],{"__ignoreMap":49},[519,1688,1689,1692],{"class":521,"line":522},[519,1690,1691],{"class":1367},"img",[519,1693,530],{"class":529},[519,1695,1696,1699,1701,1703,1705],{"class":521,"line":533},[519,1697,1698],{"class":536},"  max-width",[519,1700,540],{"class":529},[519,1702,543],{"class":536},[519,1704,547],{"class":546},[519,1706,550],{"class":529},[519,1708,1709,1711,1713,1716],{"class":521,"line":553},[519,1710,1438],{"class":536},[519,1712,540],{"class":529},[519,1714,1715],{"class":536},"auto",[519,1717,550],{"class":529},[519,1719,1720],{"class":521,"line":566},[519,1721,594],{"class":529},[35,1723,1725],{"id":1724},"use-lazy-loading-selectively","Use Lazy Loading Selectively",[11,1727,1728],{},"Images below the initial viewport can use:",[43,1730,1732],{"className":1355,"code":1731,"language":1357,"meta":49,"style":49},"\u003Cimg\n  src=\"/images/gallery-item.webp\"\n  loading=\"lazy\"\n  decoding=\"async\"\n  width=\"800\"\n  height=\"600\"\n  alt=\"Example gallery card after image compression\"\n>\n",[51,1733,1734,1740,1749,1759,1769,1777,1786,1795],{"__ignoreMap":49},[519,1735,1736,1738],{"class":521,"line":522},[519,1737,1364],{"class":529},[519,1739,1368],{"class":1367},[519,1741,1742,1744,1746],{"class":521,"line":533},[519,1743,1373],{"class":525},[519,1745,1376],{"class":529},[519,1747,1748],{"class":1379},"\"/images/gallery-item.webp\"\n",[519,1750,1751,1754,1756],{"class":521,"line":553},[519,1752,1753],{"class":525},"  loading",[519,1755,1376],{"class":529},[519,1757,1758],{"class":1379},"\"lazy\"\n",[519,1760,1761,1764,1766],{"class":521,"line":566},[519,1762,1763],{"class":525},"  decoding",[519,1765,1376],{"class":529},[519,1767,1768],{"class":1379},"\"async\"\n",[519,1770,1771,1773,1775],{"class":521,"line":578},[519,1772,537],{"class":525},[519,1774,1376],{"class":529},[519,1776,1443],{"class":1379},[519,1778,1779,1781,1783],{"class":521,"line":591},[519,1780,1438],{"class":525},[519,1782,1376],{"class":529},[519,1784,1785],{"class":1379},"\"600\"\n",[519,1787,1788,1790,1792],{"class":521,"line":1408},[519,1789,1449],{"class":525},[519,1791,1376],{"class":529},[519,1793,1794],{"class":1379},"\"Example gallery card after image compression\"\n",[519,1796,1797],{"class":521,"line":1414},[519,1798,1460],{"class":529},[11,1800,1801,1802,1805],{},"Do not lazy-load the primary hero or likely Largest Contentful Paint image. Delaying the most important visible image can make the page feel slower. Load that image normally and consider ",[51,1803,1804],{},"fetchpriority=\"high\""," only when it is genuinely the page's high-priority visual.",[35,1807,1809],{"id":1808},"image-compression-for-seo","Image Compression for SEO",[11,1811,1812],{},"Compression alone does not make an image rank. It supports a faster, more usable page, while image discovery also depends on the surrounding page.",[11,1814,729],{},[15,1816,1817,1823,1826,1829,1835,1838],{},[18,1818,1819,1820],{},"A short, descriptive filename such as ",[51,1821,1822],{},"blue-running-shoe.webp",[18,1824,1825],{},"Useful alt text that describes the image in context",[18,1827,1828],{},"Relevant nearby text or a caption",[18,1830,1831,1832,1834],{},"A standard ",[51,1833,1606],{}," element rather than a CSS background for important content",[18,1836,1837],{},"A stable, crawlable image URL",[18,1839,1840,1841,1844],{},"A representative ",[51,1842,1843],{},"og:image"," and structured-data image where relevant",[11,1846,1847],{},"Avoid keyword stuffing:",[43,1849,1851],{"className":1355,"code":1850,"language":1357,"meta":49,"style":49},"\u003C!-- Poor -->\n\u003Cimg src=\"shoe.webp\" alt=\"shoe shoes best shoes running shoe cheap shoes\">\n\n\u003C!-- Better -->\n\u003Cimg src=\"blue-running-shoe.webp\" alt=\"Blue road-running shoe viewed from the side\">\n",[51,1852,1853,1859,1883,1888,1893],{"__ignoreMap":49},[519,1854,1855],{"class":521,"line":522},[519,1856,1858],{"class":1857},"sJ8bj","\u003C!-- Poor -->\n",[519,1860,1861,1863,1865,1868,1870,1873,1876,1878,1881],{"class":521,"line":533},[519,1862,1364],{"class":529},[519,1864,1691],{"class":1367},[519,1866,1867],{"class":525}," src",[519,1869,1376],{"class":529},[519,1871,1872],{"class":1379},"\"shoe.webp\"",[519,1874,1875],{"class":525}," alt",[519,1877,1376],{"class":529},[519,1879,1880],{"class":1379},"\"shoe shoes best shoes running shoe cheap shoes\"",[519,1882,1460],{"class":529},[519,1884,1885],{"class":521,"line":553},[519,1886,1887],{"emptyLinePlaceholder":1039},"\n",[519,1889,1890],{"class":521,"line":566},[519,1891,1892],{"class":1857},"\u003C!-- Better -->\n",[519,1894,1895,1897,1899,1901,1903,1906,1908,1910,1913],{"class":521,"line":578},[519,1896,1364],{"class":529},[519,1898,1691],{"class":1367},[519,1900,1867],{"class":525},[519,1902,1376],{"class":529},[519,1904,1905],{"class":1379},"\"blue-running-shoe.webp\"",[519,1907,1875],{"class":525},[519,1909,1376],{"class":529},[519,1911,1912],{"class":1379},"\"Blue road-running shoe viewed from the side\"",[519,1914,1460],{"class":529},[11,1916,1917],{},"Alt text is primarily an accessibility feature. Write it for someone who cannot see the image, using the vocabulary that naturally fits the page.",[35,1919,1921],{"id":1920},"how-to-measure-the-result","How to Measure the Result",[11,1923,1924],{},"Record three values before and after optimization:",[60,1926,1927,1930,1933],{},[18,1928,1929],{},"File size in bytes or kilobytes",[18,1931,1932],{},"Pixel dimensions",[18,1934,1935],{},"Visual acceptability at the rendered size",[11,1937,1938],{},"Then test the real page:",[15,1940,1941,1944,1947,1950,1953],{},[18,1942,1943],{},"Open the browser's Network panel and reload with the cache disabled.",[18,1945,1946],{},"Confirm the downloaded image width matches the viewport.",[18,1948,1949],{},"Run Lighthouse or PageSpeed Insights.",[18,1951,1952],{},"Check for an oversized-image warning.",[18,1954,1955],{},"Inspect the page on a high-density phone and a desktop display.",[11,1957,1958],{},"A smaller file is not a win if text becomes unreadable, transparent edges develop halos, or a product's color changes noticeably.",[35,1960,1962],{"id":1961},"common-compression-mistakes","Common Compression Mistakes",[153,1964,1966],{"id":1965},"compressing-before-resizing","Compressing Before Resizing",[11,1968,1969],{},"The encoder spends bytes preserving pixels that will later be discarded. Resize first, then perform the final export.",[153,1971,1973],{"id":1972},"converting-every-image-to-jpeg","Converting Every Image to JPEG",[11,1975,1976],{},"JPEG can damage screenshots, text, and transparent graphics. Match the format to the content.",[153,1978,1980],{"id":1979},"saving-a-lossy-file-repeatedly","Saving a Lossy File Repeatedly",[11,1982,1983],{},"Repeated JPEG or lossy WebP exports can accumulate artifacts. Keep an original master and create delivery files from that source.",[153,1985,1987],{"id":1986},"using-one-huge-file-for-every-screen","Using One Huge File for Every Screen",[11,1989,1990],{},"Add responsive widths instead of asking a phone to download the desktop image.",[153,1992,1994],{"id":1993},"chasing-the-smallest-possible-number","Chasing the Smallest Possible Number",[11,1996,1997],{},"Compression has diminishing returns. Removing another 10 KB is not worthwhile if it introduces visible banding or unreadable detail.",[153,1999,2001],{"id":2000},"removing-important-rights-metadata","Removing Important Rights Metadata",[11,2003,2004],{},"Metadata can increase file size, but creator, copyright, or licensing information may be legally or operationally important. Preserve required rights information even when removing nonessential camera metadata.",[35,2006,896],{"id":895},[153,2008,2010],{"id":2009},"can-an-image-be-compressed-with-zero-quality-loss","Can an image be compressed with zero quality loss?",[11,2012,2013],{},"Yes, with lossless compression, but the size reduction may be smaller. Lossy compression can achieve a much smaller file while remaining visually indistinguishable at normal viewing size.",[153,2015,2017],{"id":2016},"is-webp-always-smaller-than-jpeg-or-png","Is WebP always smaller than JPEG or PNG?",[11,2019,2020],{},"Often, but not always for every encoder and image. Compare actual exports. A simple indexed PNG can be smaller than a poorly configured alternative, while some photographs benefit substantially from WebP.",[153,2022,2024],{"id":2023},"what-quality-setting-should-i-use-for-webp","What quality setting should I use for WebP?",[11,2026,2027],{},"Start around 75 to 85 for photographs and adjust after visual comparison. Screenshots and text-heavy graphics may need lossless mode or a different format.",[153,2029,2031],{"id":2030},"should-i-compress-images-before-uploading-to-a-cms","Should I compress images before uploading to a CMS?",[11,2033,2034],{},"Usually, yes, unless the CMS reliably generates correctly sized, well-compressed responsive variants. Pre-optimizing prevents oversized originals from being used accidentally.",[153,2036,2038],{"id":2037},"does-a-smaller-image-automatically-improve-core-web-vitals","Does a smaller image automatically improve Core Web Vitals?",[11,2040,2041],{},"It can reduce transfer time, but dimensions, responsive selection, caching, loading priority, and server delivery also matter. The page must use the optimized file correctly.",[35,2043,946],{"id":945},[11,2045,2046],{},"Before publishing an image:",[15,2048,2049,2052,2055,2058,2061,2064,2072,2075],{},[18,2050,2051],{},"Resize it for the largest real display size.",[18,2053,2054],{},"Choose a format appropriate for the content.",[18,2056,2057],{},"Compare quality at 100% and in the page layout.",[18,2059,2060],{},"Keep an original master file.",[18,2062,2063],{},"Generate responsive widths when needed.",[18,2065,2066,2067,774,2069,2071],{},"Set ",[51,2068,1621],{},[51,2070,1624],{},", and useful alt text.",[18,2073,2074],{},"Lazy-load only below-the-fold images.",[18,2076,2077],{},"Confirm the browser downloads the expected candidate.",[11,2079,2080],{},"Official references:",[15,2082,2083,2090,2097],{},[18,2084,2085],{},[371,2086,2089],{"href":2087,"rel":2088},"https://developer.mozilla.org/en-US/docs/Web/Media/Guides/Formats/Image_types",[388],"MDN image file type and format guide",[18,2091,2092],{},[371,2093,2096],{"href":2094,"rel":2095},"https://developers.google.com/search/docs/appearance/google-images",[388],"Google Image SEO best practices",[18,2098,2099],{},[371,2100,2103],{"href":2101,"rel":2102},"https://web.dev/learn/images/webp/",[388],"web.dev guide to WebP",[980,2105,2106],{},"html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .s9eBZ, html code.shiki .s9eBZ{--shiki-default:#22863A;--shiki-dark:#85E89D}html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}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 .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sJ8bj, html code.shiki .sJ8bj{--shiki-default:#6A737D;--shiki-dark:#6A737D}",{"title":49,"searchDepth":533,"depth":533,"links":2108},[2109,2110,2111,2116,2117,2118,2119,2120,2121,2122,2123,2131,2138],{"id":1061,"depth":533,"text":1062},{"id":1088,"depth":533,"text":1089},{"id":1121,"depth":533,"text":1122,"children":2112},[2113,2114,2115],{"id":1211,"depth":553,"text":1212},{"id":1218,"depth":553,"text":1219},{"id":1225,"depth":553,"text":1226},{"id":1235,"depth":533,"text":1236},{"id":1295,"depth":533,"text":1296},{"id":1341,"depth":533,"text":1342},{"id":1614,"depth":533,"text":1615},{"id":1724,"depth":533,"text":1725},{"id":1808,"depth":533,"text":1809},{"id":1920,"depth":533,"text":1921},{"id":1961,"depth":533,"text":1962,"children":2124},[2125,2126,2127,2128,2129,2130],{"id":1965,"depth":553,"text":1966},{"id":1972,"depth":553,"text":1973},{"id":1979,"depth":553,"text":1980},{"id":1986,"depth":553,"text":1987},{"id":1993,"depth":553,"text":1994},{"id":2000,"depth":553,"text":2001},{"id":895,"depth":533,"text":896,"children":2132},[2133,2134,2135,2136,2137],{"id":2009,"depth":553,"text":2010},{"id":2016,"depth":553,"text":2017},{"id":2023,"depth":553,"text":2024},{"id":2030,"depth":553,"text":2031},{"id":2037,"depth":553,"text":2038},{"id":945,"depth":533,"text":946},"Reduce JPG, PNG, and WebP file sizes without obvious visual damage using the right dimensions, format, quality, and responsive delivery.",{"date":1028,"updated":1028,"category":2141,"tags":2142,"order":522,"meta-description":2148,"meta-keyword":2149},"Image Optimization",[2143,1161,2144,2145,2146,2147,1036],"Image Compression","JPEG","PNG","Image SEO","Core Web Vitals","Learn how to compress images for the web without visible quality loss. Choose the right size, format, quality, and responsive image settings.","compress images for web without losing quality, web image compression, optimize images for website, WebP compression, reduce image file size","/en/blog/compress-images-for-web-without-losing-quality",{"title":1046,"description":2139},"en/blog/compress-images-for-web-without-losing-quality","byNdYYvP4tle3to2JnxJStTnCpphpmLN_johVsjkCw0",{"id":2155,"title":2156,"body":2157,"description":2390,"extension":1026,"meta":2391,"navigation":1039,"path":2400,"seo":2401,"stem":2402,"__hash__":2403},"en/en/blog/free-online-image-tools-blog.md","Free Online Image Tools: Compress, Resize, Crop, Watermark, and Split Images in Your Browser",{"type":8,"value":2158,"toc":2375},[2159,2162,2169,2173,2176,2179,2183,2187,2190,2193,2210,2213,2217,2220,2223,2226,2240,2244,2247,2250,2253,2257,2260,2263,2267,2270,2273,2277,2280,2283,2287,2290,2293,2296,2300,2303,2306,2323,2326,2330,2333,2356,2359,2363,2366,2369],[11,2160,2161],{},"Image editing is a daily task for bloggers, e-commerce teams, social media managers, photographers, marketers, and content creators. Most of the time, you do not need a heavy design app. You simply need to compress images before publishing, resize product photos to the same dimensions, crop a cover image, add a text watermark, or split a poster into a social media grid.",[11,2163,2164,2165,2168],{},"That is what ",[371,2166,389],{"href":386,"rel":2167},[388]," is built for. It is a free online image toolkit that runs directly in your browser and helps you prepare images for websites, online stores, blogs, and social platforms without uploading your original files to a server.",[35,2170,2172],{"id":2171},"what-is-vekbox-image-tools","What Is vekbox Image Tools?",[11,2174,2175],{},"vekbox Image Tools is a browser-based image processing workspace for common publishing tasks. It includes tools for image compression, format conversion, canvas resizing, proportional scaling, cropping, watermarking, and social media grid splitting.",[11,2177,2178],{},"The main advantage is privacy and speed. Your images are processed locally in the browser, which means the original files stay on your device. This makes the tool useful for product images, client assets, photography, branded content, and any image workflow where you want quick results without sending files elsewhere.",[35,2180,2182],{"id":2181},"key-features","Key Features",[153,2184,2186],{"id":2185},"_1-batch-image-compression-and-format-conversion","1. Batch Image Compression and Format Conversion",[11,2188,2189],{},"Large images can slow down websites, increase bandwidth usage, and make upload workflows frustrating. The image compression tool lets you process multiple JPG, PNG, and WebP files at once, choose a quality level, and export the optimized results in a single batch.",[11,2191,2192],{},"This is useful for:",[15,2194,2195,2198,2201,2204,2207],{},[18,2196,2197],{},"Blog images and article graphics",[18,2199,2200],{},"E-commerce product photos",[18,2202,2203],{},"Landing page visuals",[18,2205,2206],{},"Social media assets",[18,2208,2209],{},"Website performance and SEO image optimization",[11,2211,2212],{},"For many web publishing workflows, converting images to WebP or reducing file size before upload can help pages load faster while keeping visual quality suitable for visitors.",[153,2214,2216],{"id":2215},"_2-resize-images-to-the-same-canvas-size","2. Resize Images to the Same Canvas Size",[11,2218,2219],{},"When multiple images have different aspect ratios, galleries and product grids can look inconsistent. The canvas resize tool helps you place many images onto the same final width and height.",[11,2221,2222],{},"You can choose whether images should cover the canvas, fit inside it with padding, use a custom background color, preserve transparency, or export in a selected format. This is especially practical for online stores, image libraries, thumbnails, banners, and ad placements.",[11,2224,2225],{},"Common use cases include:",[15,2227,2228,2231,2234,2237],{},[18,2229,2230],{},"Making product images consistent for storefronts",[18,2232,2233],{},"Preparing square or fixed-size thumbnails",[18,2235,2236],{},"Creating clean content covers",[18,2238,2239],{},"Standardizing asset folders before upload",[153,2241,2243],{"id":2242},"_3-proportional-image-scaling","3. Proportional Image Scaling",[11,2245,2246],{},"Sometimes you do not need padding or cropping. You only need to make a large image smaller while keeping the original aspect ratio. The proportional scaling tool lets you resize images by width or height, while the other dimension is calculated automatically.",[11,2248,2249],{},"This is helpful when turning very large camera exports or design files into lighter web-ready images. For example, you can reduce a 6000px-wide image to 1600px wide before compressing it for a blog post or landing page.",[11,2251,2252],{},"Reducing pixel dimensions before compression often gives better final results than relying on quality compression alone.",[153,2254,2256],{"id":2255},"_4-crop-images-for-covers-avatars-and-social-media","4. Crop Images for Covers, Avatars, and Social Media",[11,2258,2259],{},"Cropping is one of the fastest ways to improve how an image looks in a real layout. The crop tool supports free cropping and aspect ratio presets, making it easier to prepare images for avatars, thumbnails, banners, article cards, video covers, and social media posts.",[11,2261,2262],{},"A good crop can keep the subject in focus, remove empty space, and make the final image work better in search previews, recommendation feeds, and social shares.",[153,2264,2266],{"id":2265},"_5-add-text-watermarks-online","5. Add Text Watermarks Online",[11,2268,2269],{},"Watermarks are useful for copyright protection, attribution, brand labeling, and publishing image variants across different channels. The watermark tool lets you add a text watermark directly in the browser and adjust the text, color, opacity, size, and position.",[11,2271,2272],{},"Because the watermark is rendered locally, you can prepare protected image versions without uploading original files. This is useful for photographers, designers, sellers, creators, and brands that need quick publish-ready exports.",[153,2274,2276],{"id":2275},"_6-split-images-for-social-media-grids","6. Split Images for Social Media Grids",[11,2278,2279],{},"The social media splitter turns one image into a grid, such as a 2x2 or 3x3 layout. This is useful for Instagram-style profile grids, campaign visuals, poster reveals, and multi-post social media layouts.",[11,2281,2282],{},"Before exporting, you can preview the split result and check whether important text, faces, products, or design elements land on split lines. This helps avoid publishing a grid where key visual details are accidentally broken across tiles.",[35,2284,2286],{"id":2285},"batch-processing-and-folder-friendly-exports","Batch Processing and Folder-Friendly Exports",[11,2288,2289],{},"vekbox Image Tools supports batch workflows for common image tasks. You can select multiple files, drag images into the workspace, or use folder-based workflows where supported.",[11,2291,2292],{},"When exporting multiple processed images as a Zip file, the tool can preserve the original folder structure. This is useful when working with organized product catalogs, campaign folders, client image sets, or project-based asset directories.",[11,2294,2295],{},"Instead of downloading a flat pile of files, you can keep the processed output structured and easier to manage.",[35,2297,2299],{"id":2298},"why-browser-based-image-processing-matters","Why Browser-Based Image Processing Matters",[11,2301,2302],{},"Many online image tools require uploads. That can be inconvenient for large batches and uncomfortable for private or client-owned assets. A browser-based image editor avoids that issue by doing the processing on your own device.",[11,2304,2305],{},"This approach is useful because:",[15,2307,2308,2311,2314,2317,2320],{},[18,2309,2310],{},"Original files do not need to leave your computer",[18,2312,2313],{},"Processing starts quickly without account setup",[18,2315,2316],{},"Batch image tasks become easier to repeat",[18,2318,2319],{},"Outputs can be downloaded individually or as a Zip file",[18,2321,2322],{},"The workflow stays lightweight compared with full design software",[11,2324,2325],{},"For everyday publishing work, that balance is often exactly what is needed.",[35,2327,2329],{"id":2328},"who-is-it-for","Who Is It For?",[11,2331,2332],{},"vekbox Image Tools is useful for:",[15,2334,2335,2338,2341,2344,2347,2350,2353],{},[18,2336,2337],{},"Bloggers optimizing article images",[18,2339,2340],{},"E-commerce sellers preparing product photos",[18,2342,2343],{},"Social media managers creating platform-ready visuals",[18,2345,2346],{},"Photographers adding watermarks before sharing",[18,2348,2349],{},"Designers exporting lightweight image variants",[18,2351,2352],{},"Marketers preparing campaign assets",[18,2354,2355],{},"Developers and site owners improving image performance",[11,2357,2358],{},"It is not trying to replace a full creative suite. Instead, it focuses on the image operations people need repeatedly before publishing.",[35,2360,2362],{"id":2361},"final-thoughts","Final Thoughts",[11,2364,2365],{},"If you need a free online image tool for compression, resizing, cropping, watermarking, format conversion, or social media grid splitting, vekbox Image Tools offers a practical browser-based workflow.",[11,2367,2368],{},"It is especially useful when you want to process images quickly, handle batches, keep original files private, and export ready-to-use results for blogs, websites, online stores, and social platforms.",[11,2370,2371,2372],{},"Try it here: ",[371,2373,386],{"href":386,"rel":2374},[388],{"title":49,"searchDepth":533,"depth":533,"links":2376},[2377,2378,2386,2387,2388,2389],{"id":2171,"depth":533,"text":2172},{"id":2181,"depth":533,"text":2182,"children":2379},[2380,2381,2382,2383,2384,2385],{"id":2185,"depth":553,"text":2186},{"id":2215,"depth":553,"text":2216},{"id":2242,"depth":553,"text":2243},{"id":2255,"depth":553,"text":2256},{"id":2265,"depth":553,"text":2266},{"id":2275,"depth":553,"text":2276},{"id":2285,"depth":533,"text":2286},{"id":2298,"depth":533,"text":2299},{"id":2328,"depth":533,"text":2329},{"id":2361,"depth":533,"text":2362},"Discover vekbox Image Tools, a free browser-based image toolkit for batch compression, format conversion, resizing, cropping, watermarking, and social media grid splitting with no server uploads.",{"date":2392,"category":1029,"tags":2393,"order":522,"meta-description":2398,"meta-keyword":2399},"2026-06-08",[1029,2143,1161,1032,2394,2395,2396,2397],"Crop Images","Watermark","Social Media","Browser Tools","Discover vekbox Image Tools, a free browser-based toolkit for compressing, resizing, cropping, watermarking, converting, and splitting images without server uploads.","free online image tools, online image compressor, batch image compression, resize images online, crop images online, add watermark to image, Instagram grid splitter, WebP image converter","/en/blog/free-online-image-tools-blog",{"title":2156,"description":2390},"en/blog/free-online-image-tools-blog","Jze7IXuSpg4KrUFRvxZANbSTZvGdI0JMrxC7P4wl99g",{"id":2405,"title":2406,"body":2407,"description":3660,"extension":1026,"meta":3661,"navigation":1039,"path":3673,"seo":3674,"stem":3675,"__hash__":3676},"en/en/blog/freqtrade-api-server-not-working.md","Freqtrade API Server Not Working: Fix FreqUI and Port 8080",{"type":8,"value":2408,"toc":3630},[2409,2416,2419,2434,2437,2459,2465,2469,2576,2579,2583,2590,2731,2734,2744,2751,2755,2762,2766,2768,2783,2786,2790,2797,2799,2813,2816,2853,2856,2870,2877,2881,2884,2887,2918,2928,2983,2990,2993,3026,3033,3037,3040,3044,3058,3062,3091,3094,3098,3101,3123,3130,3134,3137,3143,3146,3173,3176,3182,3187,3191,3194,3201,3241,3244,3250,3257,3263,3267,3270,3289,3292,3298,3304,3310,3326,3329,3335,3338,3342,3345,3357,3360,3362,3374,3381,3384,3419,3423,3433,3436,3453,3460,3464,3467,3496,3498,3502,3509,3517,3524,3528,3540,3544,3547,3555,3558,3560,3563,3602,3604,3627],[11,2410,2411,2412,2415],{},"When FreqUI does not load or a Freqtrade REST API request fails, the cause is usually one of four things: the API server is disabled, it is bound to the wrong interface, Docker is not publishing port ",[51,2413,2414],{},"8080",", or the client is using the wrong URL.",[11,2417,2418],{},"Start with the public health endpoint:",[43,2420,2424],{"className":2421,"code":2422,"language":2423,"meta":49,"style":49},"language-bash shiki shiki-themes github-light github-dark","curl http://127.0.0.1:8080/api/v1/ping\n","bash",[51,2425,2426],{"__ignoreMap":49},[519,2427,2428,2431],{"class":521,"line":522},[519,2429,2430],{"class":525},"curl",[519,2432,2433],{"class":1379}," http://127.0.0.1:8080/api/v1/ping\n",[11,2435,2436],{},"A working API returns:",[43,2438,2442],{"className":2439,"code":2440,"language":2441,"meta":49,"style":49},"language-json shiki shiki-themes github-light github-dark","{\"status\":\"pong\"}\n","json",[51,2443,2444],{"__ignoreMap":49},[519,2445,2446,2449,2452,2454,2457],{"class":521,"line":522},[519,2447,2448],{"class":529},"{",[519,2450,2451],{"class":536},"\"status\"",[519,2453,434],{"class":529},[519,2455,2456],{"class":1379},"\"pong\"",[519,2458,594],{"class":529},[11,2460,2461,2462,2464],{},"If that request fails, work through the checks below in order. Do not solve the problem by exposing port ",[51,2463,2414],{}," to the public internet. The Freqtrade API can control the bot and should remain behind localhost, an SSH tunnel, or a VPN.",[35,2466,2468],{"id":2467},"quick-diagnosis-by-error","Quick Diagnosis by Error",[79,2470,2471,2484],{},[82,2472,2473],{},[85,2474,2475,2478,2481],{},[88,2476,2477],{},"Symptom",[88,2479,2480],{},"Most likely cause",[88,2482,2483],{},"First check",[104,2485,2486,2499,2510,2526,2539,2554,2565],{},[85,2487,2488,2493,2496],{},[109,2489,2490],{},[51,2491,2492],{},"Connection refused",[109,2494,2495],{},"Nothing is listening on that IP and port",[109,2497,2498],{},"API enabled, process running, bind address",[85,2500,2501,2504,2507],{},[109,2502,2503],{},"Request times out",[109,2505,2506],{},"Firewall, routing, or incorrect host",[109,2508,2509],{},"Docker mapping, VPS firewall, tunnel",[85,2511,2512,2517,2520],{},[109,2513,2514],{},[51,2515,2516],{},"{\"detail\":\"Not Found\"}",[109,2518,2519],{},"Incorrect path",[109,2521,2522,2523],{},"Use ",[51,2524,2525],{},"/api/v1/ping",[85,2527,2528,2533,2536],{},[109,2529,2530],{},[51,2531,2532],{},"401 Unauthorized",[109,2534,2535],{},"Protected endpoint needs credentials",[109,2537,2538],{},"Username, password, token flow",[85,2540,2541,2544,2547],{},[109,2542,2543],{},"Browser shows a CORS error",[109,2545,2546],{},"Frontend and API use different origins",[109,2548,2549,2550,2553],{},"Exact ",[51,2551,2552],{},"CORS_origins"," value",[85,2555,2556,2559,2562],{},[109,2557,2558],{},"Local curl works, remote browser fails",[109,2560,2561],{},"API is intentionally bound to localhost",[109,2563,2564],{},"Use an SSH tunnel or VPN",[85,2566,2567,2570,2573],{},[109,2568,2569],{},"FreqUI opens but exchange data fails",[109,2571,2572],{},"Exchange connectivity is the problem",[109,2574,2575],{},"Proxy, DNS, clock, API credentials",[11,2577,2578],{},"This table helps separate an API listener problem from an exchange connection problem. They occur in different parts of the stack and require different fixes.",[35,2580,2582],{"id":2581},"step-1-enable-the-api-server","Step 1: Enable the API Server",[11,2584,2585,2586,2589],{},"Add an ",[51,2587,2588],{},"api_server"," section to the configuration file that the running bot actually loads:",[43,2591,2593],{"className":2439,"code":2592,"language":2441,"meta":49,"style":49},"{\n  \"api_server\": {\n    \"enabled\": true,\n    \"listen_ip_address\": \"127.0.0.1\",\n    \"listen_port\": 8080,\n    \"verbosity\": \"error\",\n    \"enable_openapi\": false,\n    \"jwt_secret_key\": \"replace-with-a-random-secret-at-least-32-characters\",\n    \"CORS_origins\": [],\n    \"username\": \"Freqtrader\",\n    \"password\": \"replace-with-a-strong-unique-password\",\n    \"ws_token\": \"replace-with-a-random-websocket-token\"\n  }\n}\n",[51,2594,2595,2600,2608,2621,2633,2644,2656,2668,2680,2688,2700,2712,2722,2727],{"__ignoreMap":49},[519,2596,2597],{"class":521,"line":522},[519,2598,2599],{"class":529},"{\n",[519,2601,2602,2605],{"class":521,"line":533},[519,2603,2604],{"class":536},"  \"api_server\"",[519,2606,2607],{"class":529},": {\n",[519,2609,2610,2613,2615,2618],{"class":521,"line":553},[519,2611,2612],{"class":536},"    \"enabled\"",[519,2614,540],{"class":529},[519,2616,2617],{"class":536},"true",[519,2619,2620],{"class":529},",\n",[519,2622,2623,2626,2628,2631],{"class":521,"line":566},[519,2624,2625],{"class":536},"    \"listen_ip_address\"",[519,2627,540],{"class":529},[519,2629,2630],{"class":1379},"\"127.0.0.1\"",[519,2632,2620],{"class":529},[519,2634,2635,2638,2640,2642],{"class":521,"line":578},[519,2636,2637],{"class":536},"    \"listen_port\"",[519,2639,540],{"class":529},[519,2641,2414],{"class":536},[519,2643,2620],{"class":529},[519,2645,2646,2649,2651,2654],{"class":521,"line":591},[519,2647,2648],{"class":536},"    \"verbosity\"",[519,2650,540],{"class":529},[519,2652,2653],{"class":1379},"\"error\"",[519,2655,2620],{"class":529},[519,2657,2658,2661,2663,2666],{"class":521,"line":1408},[519,2659,2660],{"class":536},"    \"enable_openapi\"",[519,2662,540],{"class":529},[519,2664,2665],{"class":536},"false",[519,2667,2620],{"class":529},[519,2669,2670,2673,2675,2678],{"class":521,"line":1414},[519,2671,2672],{"class":536},"    \"jwt_secret_key\"",[519,2674,540],{"class":529},[519,2676,2677],{"class":1379},"\"replace-with-a-random-secret-at-least-32-characters\"",[519,2679,2620],{"class":529},[519,2681,2682,2685],{"class":521,"line":1425},[519,2683,2684],{"class":536},"    \"CORS_origins\"",[519,2686,2687],{"class":529},": [],\n",[519,2689,2690,2693,2695,2698],{"class":521,"line":1435},[519,2691,2692],{"class":536},"    \"username\"",[519,2694,540],{"class":529},[519,2696,2697],{"class":1379},"\"Freqtrader\"",[519,2699,2620],{"class":529},[519,2701,2702,2705,2707,2710],{"class":521,"line":1446},[519,2703,2704],{"class":536},"    \"password\"",[519,2706,540],{"class":529},[519,2708,2709],{"class":1379},"\"replace-with-a-strong-unique-password\"",[519,2711,2620],{"class":529},[519,2713,2714,2717,2719],{"class":521,"line":1457},[519,2715,2716],{"class":536},"    \"ws_token\"",[519,2718,540],{"class":529},[519,2720,2721],{"class":1379},"\"replace-with-a-random-websocket-token\"\n",[519,2723,2724],{"class":521,"line":1584},[519,2725,2726],{"class":529},"  }\n",[519,2728,2729],{"class":521,"line":1589},[519,2730,594],{"class":529},[11,2732,2733],{},"Restart Freqtrade after changing the configuration. Then test:",[43,2735,2736],{"className":2421,"code":2422,"language":2423,"meta":49,"style":49},[51,2737,2738],{"__ignoreMap":49},[519,2739,2740,2742],{"class":521,"line":522},[519,2741,2430],{"class":525},[519,2743,2433],{"class":1379},[11,2745,2746,2747,2750],{},"If Freqtrade starts with more than one config file, later files and environment variables can override earlier values. Use the same ",[51,2748,2749],{},"--config"," arguments for both testing and normal operation.",[35,2752,2754],{"id":2753},"step-2-use-the-correct-bind-address","Step 2: Use the Correct Bind Address",[11,2756,2757,2758,2761],{},"The correct ",[51,2759,2760],{},"listen_ip_address"," depends on where Freqtrade runs.",[153,2763,2765],{"id":2764},"local-installation","Local Installation",[11,2767,729],{},[43,2769,2771],{"className":2439,"code":2770,"language":2441,"meta":49,"style":49},"\"listen_ip_address\": \"127.0.0.1\"\n",[51,2772,2773],{"__ignoreMap":49},[519,2774,2775,2778,2780],{"class":521,"line":522},[519,2776,2777],{"class":1379},"\"listen_ip_address\"",[519,2779,540],{"class":529},[519,2781,2782],{"class":1379},"\"127.0.0.1\"\n",[11,2784,2785],{},"This accepts connections from the same machine only. It is the safest default.",[153,2787,2789],{"id":2788},"docker-container","Docker Container",[11,2791,2792,2793,2796],{},"Inside a container, ",[51,2794,2795],{},"127.0.0.1"," means the container itself. Docker cannot forward a host connection to a service that only accepts loopback traffic inside the container.",[11,2798,729],{},[43,2800,2802],{"className":2439,"code":2801,"language":2441,"meta":49,"style":49},"\"listen_ip_address\": \"0.0.0.0\"\n",[51,2803,2804],{"__ignoreMap":49},[519,2805,2806,2808,2810],{"class":521,"line":522},[519,2807,2777],{"class":1379},[519,2809,540],{"class":529},[519,2811,2812],{"class":1379},"\"0.0.0.0\"\n",[11,2814,2815],{},"Then restrict exposure with the host-side port mapping:",[43,2817,2821],{"className":2818,"code":2819,"language":2820,"meta":49,"style":49},"language-yaml shiki shiki-themes github-light github-dark","services:\n  freqtrade:\n    ports:\n      - \"127.0.0.1:8080:8080\"\n","yaml",[51,2822,2823,2831,2838,2845],{"__ignoreMap":49},[519,2824,2825,2828],{"class":521,"line":522},[519,2826,2827],{"class":1367},"services",[519,2829,2830],{"class":529},":\n",[519,2832,2833,2836],{"class":521,"line":533},[519,2834,2835],{"class":1367},"  freqtrade",[519,2837,2830],{"class":529},[519,2839,2840,2843],{"class":521,"line":553},[519,2841,2842],{"class":1367},"    ports",[519,2844,2830],{"class":529},[519,2846,2847,2850],{"class":521,"line":566},[519,2848,2849],{"class":529},"      - ",[519,2851,2852],{"class":1379},"\"127.0.0.1:8080:8080\"\n",[11,2854,2855],{},"This combination has two distinct jobs:",[15,2857,2858,2864],{},[18,2859,2860,2863],{},[51,2861,2862],{},"0.0.0.0"," lets the service receive traffic arriving through the container network.",[18,2865,2866,2869],{},[51,2867,2868],{},"127.0.0.1:8080:8080"," publishes the port only on the Docker host's loopback interface.",[11,2871,2872,2873,2876],{},"Avoid a bare mapping such as ",[51,2874,2875],{},"\"8080:8080\""," on an internet-facing server. It may make the API reachable from outside the machine.",[35,2878,2880],{"id":2879},"step-3-confirm-the-running-process-uses-your-config","Step 3: Confirm the Running Process Uses Your Config",[11,2882,2883],{},"Editing the right-looking file is not enough if the container or service loads a different path.",[11,2885,2886],{},"For Docker Compose, inspect the effective service and logs:",[43,2888,2890],{"className":2421,"code":2889,"language":2423,"meta":49,"style":49},"docker compose ps\ndocker compose logs --tail=100 freqtrade\n",[51,2891,2892,2903],{"__ignoreMap":49},[519,2893,2894,2897,2900],{"class":521,"line":522},[519,2895,2896],{"class":525},"docker",[519,2898,2899],{"class":1379}," compose",[519,2901,2902],{"class":1379}," ps\n",[519,2904,2905,2907,2909,2912,2915],{"class":521,"line":533},[519,2906,2896],{"class":525},[519,2908,2899],{"class":1379},[519,2910,2911],{"class":1379}," logs",[519,2913,2914],{"class":536}," --tail=100",[519,2916,2917],{"class":1379}," freqtrade\n",[11,2919,2920,2921,2924,2925,434],{},"Check the ",[51,2922,2923],{},"command"," and mounted volume in ",[51,2926,2927],{},"docker-compose.yml",[43,2929,2931],{"className":2818,"code":2930,"language":2820,"meta":49,"style":49},"services:\n  freqtrade:\n    volumes:\n      - \"./user_data:/freqtrade/user_data\"\n    command: >\n      trade\n      --config /freqtrade/user_data/config.json\n      --strategy SampleStrategy\n",[51,2932,2933,2939,2945,2952,2959,2968,2973,2978],{"__ignoreMap":49},[519,2934,2935,2937],{"class":521,"line":522},[519,2936,2827],{"class":1367},[519,2938,2830],{"class":529},[519,2940,2941,2943],{"class":521,"line":533},[519,2942,2835],{"class":1367},[519,2944,2830],{"class":529},[519,2946,2947,2950],{"class":521,"line":553},[519,2948,2949],{"class":1367},"    volumes",[519,2951,2830],{"class":529},[519,2953,2954,2956],{"class":521,"line":566},[519,2955,2849],{"class":529},[519,2957,2958],{"class":1379},"\"./user_data:/freqtrade/user_data\"\n",[519,2960,2961,2964,2966],{"class":521,"line":578},[519,2962,2963],{"class":1367},"    command",[519,2965,540],{"class":529},[519,2967,1460],{"class":546},[519,2969,2970],{"class":521,"line":591},[519,2971,2972],{"class":1379},"      trade\n",[519,2974,2975],{"class":521,"line":1408},[519,2976,2977],{"class":1379},"      --config /freqtrade/user_data/config.json\n",[519,2979,2980],{"class":521,"line":1414},[519,2981,2982],{"class":1379},"      --strategy SampleStrategy\n",[11,2984,2985,2986,2989],{},"If your service has a different name, replace ",[51,2987,2988],{},"freqtrade"," in the log command.",[11,2991,2992],{},"For a script or virtual environment installation, start the bot with the intended file explicitly:",[43,2994,2996],{"className":2421,"code":2995,"language":2423,"meta":49,"style":49},"freqtrade trade \\\n  --config user_data/config.json \\\n  --strategy SampleStrategy\n",[51,2997,2998,3008,3018],{"__ignoreMap":49},[519,2999,3000,3002,3005],{"class":521,"line":522},[519,3001,2988],{"class":525},[519,3003,3004],{"class":1379}," trade",[519,3006,3007],{"class":536}," \\\n",[519,3009,3010,3013,3016],{"class":521,"line":533},[519,3011,3012],{"class":536},"  --config",[519,3014,3015],{"class":1379}," user_data/config.json",[519,3017,3007],{"class":536},[519,3019,3020,3023],{"class":521,"line":553},[519,3021,3022],{"class":536},"  --strategy",[519,3024,3025],{"class":1379}," SampleStrategy\n",[11,3027,3028,3029,3032],{},"Look for configuration validation errors or an ",[51,3030,3031],{},"Address already in use"," message. A malformed config may prevent the API from starting even if the trading process appears to launch.",[35,3034,3036],{"id":3035},"step-4-test-from-each-network-layer","Step 4: Test from Each Network Layer",[11,3038,3039],{},"Testing from the right location reveals where connectivity stops.",[153,3041,3043],{"id":3042},"test-on-the-host","Test on the Host",[43,3045,3047],{"className":2421,"code":3046,"language":2423,"meta":49,"style":49},"curl -v http://127.0.0.1:8080/api/v1/ping\n",[51,3048,3049],{"__ignoreMap":49},[519,3050,3051,3053,3056],{"class":521,"line":522},[519,3052,2430],{"class":525},[519,3054,3055],{"class":536}," -v",[519,3057,2433],{"class":1379},[153,3059,3061],{"id":3060},"test-inside-the-container","Test Inside the Container",[43,3063,3065],{"className":2421,"code":3064,"language":2423,"meta":49,"style":49},"docker compose exec freqtrade \\\n  curl -s http://127.0.0.1:8080/api/v1/ping\n",[51,3066,3067,3081],{"__ignoreMap":49},[519,3068,3069,3071,3073,3076,3079],{"class":521,"line":522},[519,3070,2896],{"class":525},[519,3072,2899],{"class":1379},[519,3074,3075],{"class":1379}," exec",[519,3077,3078],{"class":1379}," freqtrade",[519,3080,3007],{"class":536},[519,3082,3083,3086,3089],{"class":521,"line":533},[519,3084,3085],{"class":1379},"  curl",[519,3087,3088],{"class":536}," -s",[519,3090,2433],{"class":1379},[11,3092,3093],{},"If the request works inside the container but not on the host, inspect the bind address and Docker port mapping.",[153,3095,3097],{"id":3096},"check-whether-the-port-is-listening","Check Whether the Port Is Listening",[11,3099,3100],{},"On Linux:",[43,3102,3104],{"className":2421,"code":3103,"language":2423,"meta":49,"style":49},"ss -ltnp | grep 8080\n",[51,3105,3106],{"__ignoreMap":49},[519,3107,3108,3111,3114,3117,3120],{"class":521,"line":522},[519,3109,3110],{"class":525},"ss",[519,3112,3113],{"class":536}," -ltnp",[519,3115,3116],{"class":546}," |",[519,3118,3119],{"class":525}," grep",[519,3121,3122],{"class":536}," 8080\n",[11,3124,3125,3126,3129],{},"Expected local-only Docker output normally includes a listener on ",[51,3127,3128],{},"127.0.0.1:8080",". If there is no listener, the API did not start or the port was not published.",[35,3131,3133],{"id":3132},"step-5-use-the-correct-url","Step 5: Use the Correct URL",[11,3135,3136],{},"The health-check URL is:",[43,3138,3141],{"className":3139,"code":3140,"language":48,"meta":49},[46],"http://127.0.0.1:8080/api/v1/ping\n",[51,3142,3140],{"__ignoreMap":49},[11,3144,3145],{},"Common URL mistakes include:",[15,3147,3148,3155,3161,3167,3170],{},[18,3149,3150,3151,3154],{},"Opening ",[51,3152,3153],{},"/api/v1"," without an endpoint.",[18,3156,430,3157,3160],{},[51,3158,3159],{},"https://"," when no reverse proxy provides TLS.",[18,3162,430,3163,3166],{},[51,3164,3165],{},"localhost"," from another container and expecting it to reach Freqtrade.",[18,3168,3169],{},"Using the public VPS IP while the service is correctly bound to localhost.",[18,3171,3172],{},"Sending a protected request without authentication.",[11,3174,3175],{},"Within a Compose network, another container should normally use the Freqtrade service name:",[43,3177,3180],{"className":3178,"code":3179,"language":48,"meta":49},[46],"http://freqtrade:8080/api/v1/ping\n",[51,3181,3179],{"__ignoreMap":49},[11,3183,3184,3185,390],{},"The exact hostname is the Compose service name, not automatically the container name or ",[51,3186,3165],{},[35,3188,3190],{"id":3189},"step-6-fix-frequi-cors-errors","Step 6: Fix FreqUI CORS Errors",[11,3192,3193],{},"CORS matters when the browser loads FreqUI from an origin different from the API origin. An origin consists of the scheme, hostname, and port.",[11,3195,3196,3197,3200],{},"For a UI served from ",[51,3198,3199],{},"https://trading.example.com",", configure:",[43,3202,3204],{"className":2439,"code":3203,"language":2441,"meta":49,"style":49},"{\n  \"api_server\": {\n    \"CORS_origins\": [\n      \"https://trading.example.com\"\n    ]\n  }\n}\n",[51,3205,3206,3210,3216,3223,3228,3233,3237],{"__ignoreMap":49},[519,3207,3208],{"class":521,"line":522},[519,3209,2599],{"class":529},[519,3211,3212,3214],{"class":521,"line":533},[519,3213,2604],{"class":536},[519,3215,2607],{"class":529},[519,3217,3218,3220],{"class":521,"line":553},[519,3219,2684],{"class":536},[519,3221,3222],{"class":529},": [\n",[519,3224,3225],{"class":521,"line":566},[519,3226,3227],{"class":1379},"      \"https://trading.example.com\"\n",[519,3229,3230],{"class":521,"line":578},[519,3231,3232],{"class":529},"    ]\n",[519,3234,3235],{"class":521,"line":591},[519,3236,2726],{"class":529},[519,3238,3239],{"class":521,"line":1408},[519,3240,594],{"class":529},[11,3242,3243],{},"Do not add a trailing slash:",[43,3245,3248],{"className":3246,"code":3247,"language":48,"meta":49},[46],"Correct:   https://trading.example.com\nIncorrect: https://trading.example.com/\n",[51,3249,3247],{"__ignoreMap":49},[11,3251,3252,3253,3256],{},"Do not use ",[51,3254,3255],{},"*"," with authenticated browser requests. Allow only the exact trusted origins that need access.",[11,3258,3259,3260,3262],{},"A CORS error is a browser policy error. If ",[51,3261,2430],{}," cannot connect at all, fix the listener or network path before changing CORS.",[35,3264,3266],{"id":3265},"step-7-access-frequi-on-a-vps-safely","Step 7: Access FreqUI on a VPS Safely",[11,3268,3269],{},"The recommended pattern is to leave Freqtrade on localhost and create an SSH tunnel from your computer:",[43,3271,3273],{"className":2421,"code":3272,"language":2423,"meta":49,"style":49},"ssh -L 8080:127.0.0.1:8080 user@your-server\n",[51,3274,3275],{"__ignoreMap":49},[519,3276,3277,3280,3283,3286],{"class":521,"line":522},[519,3278,3279],{"class":525},"ssh",[519,3281,3282],{"class":536}," -L",[519,3284,3285],{"class":1379}," 8080:127.0.0.1:8080",[519,3287,3288],{"class":1379}," user@your-server\n",[11,3290,3291],{},"Keep the SSH session open, then visit:",[43,3293,3296],{"className":3294,"code":3295,"language":48,"meta":49},[46],"http://127.0.0.1:8080\n",[51,3297,3295],{"__ignoreMap":49},[11,3299,3300,3301,3303],{},"Traffic travels through the encrypted SSH connection, while port ",[51,3302,2414],{}," remains closed to the public internet.",[11,3305,3306,3307,3309],{},"If local port ",[51,3308,2414],{}," is already occupied, use a different local port:",[43,3311,3313],{"className":2421,"code":3312,"language":2423,"meta":49,"style":49},"ssh -L 18080:127.0.0.1:8080 user@your-server\n",[51,3314,3315],{"__ignoreMap":49},[519,3316,3317,3319,3321,3324],{"class":521,"line":522},[519,3318,3279],{"class":525},[519,3320,3282],{"class":536},[519,3322,3323],{"class":1379}," 18080:127.0.0.1:8080",[519,3325,3288],{"class":1379},[11,3327,3328],{},"Then open:",[43,3330,3333],{"className":3331,"code":3332,"language":48,"meta":49},[46],"http://127.0.0.1:18080\n",[51,3334,3332],{"__ignoreMap":49},[11,3336,3337],{},"A private VPN such as WireGuard is another suitable option. A reverse proxy can add HTTPS, but it does not make unrestricted public API exposure safe by itself.",[35,3339,3341],{"id":3340},"step-8-distinguish-trade-mode-from-webserver-mode","Step 8: Distinguish Trade Mode from Webserver Mode",[11,3343,3344],{},"Running:",[43,3346,3348],{"className":2421,"code":3347,"language":2423,"meta":49,"style":49},"freqtrade trade\n",[51,3349,3350],{"__ignoreMap":49},[519,3351,3352,3354],{"class":521,"line":522},[519,3353,2988],{"class":525},[519,3355,3356],{"class":1379}," trade\n",[11,3358,3359],{},"starts the trading or dry-run process. When the API server is enabled, FreqUI is available through the configured API port.",[11,3361,3344],{},[43,3363,3365],{"className":2421,"code":3364,"language":2423,"meta":49,"style":49},"freqtrade webserver\n",[51,3366,3367],{"__ignoreMap":49},[519,3368,3369,3371],{"class":521,"line":522},[519,3370,2988],{"class":525},[519,3372,3373],{"class":1379}," webserver\n",[11,3375,3376,3377,3380],{},"starts the separate webserver workflow used for tasks such as strategy development and backtesting. Do not leave the command set to ",[51,3378,3379],{},"webserver"," when you expect the bot to trade.",[11,3382,3383],{},"For a one-off Docker webserver session, the port must be published explicitly if it is not already part of the service configuration:",[43,3385,3387],{"className":2421,"code":3386,"language":2423,"meta":49,"style":49},"docker compose run --rm \\\n  -p 127.0.0.1:8080:8080 \\\n  freqtrade webserver\n",[51,3388,3389,3403,3413],{"__ignoreMap":49},[519,3390,3391,3393,3395,3398,3401],{"class":521,"line":522},[519,3392,2896],{"class":525},[519,3394,2899],{"class":1379},[519,3396,3397],{"class":1379}," run",[519,3399,3400],{"class":536}," --rm",[519,3402,3007],{"class":536},[519,3404,3405,3408,3411],{"class":521,"line":533},[519,3406,3407],{"class":536},"  -p",[519,3409,3410],{"class":1379}," 127.0.0.1:8080:8080",[519,3412,3007],{"class":536},[519,3414,3415,3417],{"class":521,"line":553},[519,3416,2835],{"class":1379},[519,3418,3373],{"class":1379},[35,3420,3422],{"id":3421},"when-the-api-works-but-the-exchange-does-not","When the API Works but the Exchange Does Not",[11,3424,3425,3426,3428,3429,3432],{},"If ",[51,3427,2525],{}," returns ",[51,3430,3431],{},"pong"," and FreqUI loads, the API server is functioning. Errors while loading markets, candles, or balances point elsewhere.",[11,3434,3435],{},"Check:",[15,3437,3438,3441,3444,3447,3450],{},[18,3439,3440],{},"Exchange API credentials and permissions",[18,3442,3443],{},"DNS resolution",[18,3445,3446],{},"System clock synchronization",[18,3448,3449],{},"Exchange availability or rate limits",[18,3451,3452],{},"Proxy configuration passed to CCXT",[11,3454,3455,3456,390],{},"For a proxy-specific failure, follow the ",[371,3457,3459],{"href":3458},"/blog/freqtrade-proxy-not-working/","Freqtrade proxy troubleshooting guide",[35,3461,3463],{"id":3462},"security-checklist","Security Checklist",[11,3465,3466],{},"Before considering the issue resolved:",[60,3468,3469,3475,3478,3481,3484,3487,3490],{},[18,3470,3471,3472,3474],{},"Keep the host binding on ",[51,3473,2795],{}," whenever possible.",[18,3476,3477],{},"Use a unique password and a random JWT secret of at least 32 characters.",[18,3479,3480],{},"Use a random WebSocket token.",[18,3482,3483],{},"Do not commit secrets to Git.",[18,3485,3486],{},"Prefer an SSH tunnel or VPN for remote access.",[18,3488,3489],{},"Keep Freqtrade updated for current exchange compatibility and security fixes.",[18,3491,3492,3493,3495],{},"Verify from an external network that port ",[51,3494,2414],{}," is not publicly reachable.",[35,3497,896],{"id":895},[153,3499,3501],{"id":3500},"why-does-frequi-show-a-blank-page","Why does FreqUI show a blank page?",[11,3503,3504,3505,3428,3507,390],{},"Check the browser console and the Freqtrade logs. A failed API request, incorrect base URL, CORS mismatch, or incompatible cached UI assets can all produce a blank interface. First confirm that ",[51,3506,2525],{},[51,3508,3431],{},[153,3510,3512,3513,3516],{"id":3511},"why-does-localhost8080-fail-from-another-container","Why does ",[51,3514,3515],{},"localhost:8080"," fail from another container?",[11,3518,3519,3520,3523],{},"Each container has its own loopback interface. Use the Compose service name, such as ",[51,3521,3522],{},"http://freqtrade:8080",", and make sure both services share a Docker network.",[153,3525,3527],{"id":3526},"why-does-the-api-work-inside-docker-but-not-on-the-host","Why does the API work inside Docker but not on the host?",[11,3529,3530,3531,3533,3534,3536,3537,3539],{},"The API may be bound to ",[51,3532,2795],{}," inside the container, or Compose may not publish the port. Bind to ",[51,3535,2862],{}," inside the container and publish it as ",[51,3538,2868],{}," on the host.",[153,3541,3543],{"id":3542},"is-it-safe-to-open-port-8080-in-the-vps-firewall","Is it safe to open port 8080 in the VPS firewall?",[11,3545,3546],{},"Public exposure is not recommended. The API can perform sensitive bot actions. Use an SSH tunnel or a VPN instead.",[153,3548,3550,3551,3554],{"id":3549},"why-do-protected-endpoints-return-401-while-ping-works","Why do protected endpoints return 401 while ",[51,3552,3553],{},"/ping"," works?",[11,3556,3557],{},"The ping endpoint is public so it can report readiness. Other endpoints require the configured credentials or an access token.",[35,3559,946],{"id":945},[11,3561,3562],{},"A secure working setup should satisfy all of these conditions:",[15,3564,3565,3573,3578,3584,3589,3596,3599],{},[18,3566,3567,3570,3571,390],{},[51,3568,3569],{},"api_server.enabled"," is ",[51,3572,2617],{},[18,3574,3575,3576,390],{},"Local installs bind to ",[51,3577,2795],{},[18,3579,3580,3581,3583],{},"Docker installs bind to ",[51,3582,2862],{}," inside the container.",[18,3585,3586,3587,3539],{},"Docker publishes ",[51,3588,2868],{},[18,3590,3591,3428,3593,390],{},[51,3592,2525],{},[51,3594,3595],{},"{\"status\":\"pong\"}",[18,3597,3598],{},"CORS contains only exact trusted origins when cross-origin access is required.",[18,3600,3601],{},"Remote access uses an SSH tunnel or VPN.",[11,3603,2080],{},[15,3605,3606,3613,3620],{},[18,3607,3608],{},[371,3609,3612],{"href":3610,"rel":3611},"https://docs.freqtrade.io/en/stable/rest-api/",[388],"Freqtrade REST API documentation",[18,3614,3615],{},[371,3616,3619],{"href":3617,"rel":3618},"https://docs.freqtrade.io/en/stable/configuration/",[388],"Freqtrade configuration guide",[18,3621,3622],{},[371,3623,3626],{"href":3624,"rel":3625},"https://docs.freqtrade.io/en/stable/utils/",[388],"Freqtrade utility commands and webserver mode",[980,3628,3629],{},"html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}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 .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .s9eBZ, html code.shiki .s9eBZ{--shiki-default:#22863A;--shiki-dark:#85E89D}html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}",{"title":49,"searchDepth":533,"depth":533,"links":3631},[3632,3633,3634,3638,3639,3644,3645,3646,3647,3648,3649,3650,3659],{"id":2467,"depth":533,"text":2468},{"id":2581,"depth":533,"text":2582},{"id":2753,"depth":533,"text":2754,"children":3635},[3636,3637],{"id":2764,"depth":553,"text":2765},{"id":2788,"depth":553,"text":2789},{"id":2879,"depth":533,"text":2880},{"id":3035,"depth":533,"text":3036,"children":3640},[3641,3642,3643],{"id":3042,"depth":553,"text":3043},{"id":3060,"depth":553,"text":3061},{"id":3096,"depth":553,"text":3097},{"id":3132,"depth":533,"text":3133},{"id":3189,"depth":533,"text":3190},{"id":3265,"depth":533,"text":3266},{"id":3340,"depth":533,"text":3341},{"id":3421,"depth":533,"text":3422},{"id":3462,"depth":533,"text":3463},{"id":895,"depth":533,"text":896,"children":3651},[3652,3653,3655,3656,3657],{"id":3500,"depth":553,"text":3501},{"id":3511,"depth":553,"text":3654},"Why does localhost:8080 fail from another container?",{"id":3526,"depth":553,"text":3527},{"id":3542,"depth":553,"text":3543},{"id":3549,"depth":553,"text":3658},"Why do protected endpoints return 401 while /ping works?",{"id":945,"depth":533,"text":946},"Troubleshoot Freqtrade API and FreqUI connection errors in local, Docker, and VPS setups without exposing your trading bot to the internet.",{"date":1028,"updated":1028,"category":3662,"tags":3663,"order":522,"meta-description":3671,"meta-keyword":3672},"Trading Bot",[3664,3665,3666,3667,3668,3669,3670,3662],"Freqtrade","FreqUI","REST API","Docker","Port 8080","VPS","Troubleshooting","Fix Freqtrade API server and FreqUI connection errors. Check api_server settings, Docker port 8080, CORS, ping, logs, and secure remote access.","Freqtrade API server not working, FreqUI not loading, Freqtrade port 8080, Freqtrade Docker API, Freqtrade connection refused","/en/blog/freqtrade-api-server-not-working",{"title":2406,"description":3660},"en/blog/freqtrade-api-server-not-working","Sa3VmEPDXpu1FUyCJcn6aAb8DEJ5G_EFcl7J4MVccek",{"id":3678,"title":3679,"body":3680,"description":3852,"extension":1026,"meta":3853,"navigation":1039,"path":3864,"seo":3865,"stem":3866,"__hash__":3867},"en/en/blog/freqtrade-proxy-not-working.md","Fix: Freqtrade Proxy Not Working",{"type":8,"value":3681,"toc":3850},[3682,3688,3699,3717,3720,3733,3791,3797,3811,3817,3847],[11,3683,3684,3685,3687],{},"When using ",[21,3686,3664],{},", to bypass specific network restrictions, you often need to configure a proxy for exchange connections. However, you might find that even after adding the proxy parameters, the program still fails to communicate through the proxy network.",[11,3689,3690,3691,3694,3695,3698],{},"This situation usually happens for two reasons: First, the proxy configuration level or key name in your ",[51,3692,3693],{},"config.json"," is incorrect. Second, certain Freqtrade versions installed via ",[51,3696,3697],{},"pip"," have compatibility issues or lose context when underlying dependencies (like CCXT) handle proxy passing.",[11,3700,3701,3702,3705,3706,3709,3710,3712,3713,3716],{},"✅ ",[21,3703,3704],{},"Solution:"," Ensure you use the standard ",[51,3707,3708],{},"ccxt_config"," proxy format. If the format is correct but the proxy is still ignored, uninstall the ",[51,3711,3697],{}," version and instead pull the source code via ",[51,3714,3715],{},"git"," to run it.",[11,3718,3719],{},"Here are the complete steps to fix it:",[11,3721,3722,3725,3726,3728,3729,3732],{},[21,3723,3724],{},"1. Use the standard proxy configuration format","\nOpen your ",[51,3727,3693],{}," file and ensure the proxy parameters are strictly defined under the ",[51,3730,3731],{},"exchange.ccxt_config"," node:",[43,3734,3736],{"className":2439,"code":3735,"language":2441,"meta":49,"style":49},"{\n  \"exchange\": {\n    \"ccxt_config\": {\n      \"httpsProxy\": \"http://addr:port\",\n      \"wsProxy\": \"http://addr:port\"\n    }\n  }\n}\n",[51,3737,3738,3742,3749,3756,3768,3778,3783,3787],{"__ignoreMap":49},[519,3739,3740],{"class":521,"line":522},[519,3741,2599],{"class":529},[519,3743,3744,3747],{"class":521,"line":533},[519,3745,3746],{"class":536},"  \"exchange\"",[519,3748,2607],{"class":529},[519,3750,3751,3754],{"class":521,"line":553},[519,3752,3753],{"class":536},"    \"ccxt_config\"",[519,3755,2607],{"class":529},[519,3757,3758,3761,3763,3766],{"class":521,"line":566},[519,3759,3760],{"class":536},"      \"httpsProxy\"",[519,3762,540],{"class":529},[519,3764,3765],{"class":1379},"\"http://addr:port\"",[519,3767,2620],{"class":529},[519,3769,3770,3773,3775],{"class":521,"line":578},[519,3771,3772],{"class":536},"      \"wsProxy\"",[519,3774,540],{"class":529},[519,3776,3777],{"class":1379},"\"http://addr:port\"\n",[519,3779,3780],{"class":521,"line":591},[519,3781,3782],{"class":529},"    }\n",[519,3784,3785],{"class":521,"line":1408},[519,3786,2726],{"class":529},[519,3788,3789],{"class":521,"line":1414},[519,3790,594],{"class":529},[11,3792,3793,3796],{},[21,3794,3795],{},"2. Uninstall the ineffective pip version","\nIf the configuration is confirmed to be correct but the proxy still doesn't work, uninstall Freqtrade from your current environment in the terminal:",[43,3798,3800],{"className":2421,"code":3799,"language":2423,"meta":49,"style":49},"pip uninstall freqtrade\n",[51,3801,3802],{"__ignoreMap":49},[519,3803,3804,3806,3809],{"class":521,"line":522},[519,3805,3697],{"class":525},[519,3807,3808],{"class":1379}," uninstall",[519,3810,2917],{"class":1379},[11,3812,3813,3816],{},[21,3814,3815],{},"3. Pull the source code using Git and reconfigure the environment","\nPull the latest code directly from the official repository and use the provided script to reinitialize the environment. This typically resolves proxy network anomalies caused by solidified pip package dependencies:",[43,3818,3820],{"className":2421,"code":3819,"language":2423,"meta":49,"style":49},"git clone https://github.com/freqtrade/freqtrade.git\ncd freqtrade\n./setup.sh -i\n",[51,3821,3822,3832,3839],{"__ignoreMap":49},[519,3823,3824,3826,3829],{"class":521,"line":522},[519,3825,3715],{"class":525},[519,3827,3828],{"class":1379}," clone",[519,3830,3831],{"class":1379}," https://github.com/freqtrade/freqtrade.git\n",[519,3833,3834,3837],{"class":521,"line":533},[519,3835,3836],{"class":536},"cd",[519,3838,2917],{"class":1379},[519,3840,3841,3844],{"class":521,"line":553},[519,3842,3843],{"class":525},"./setup.sh",[519,3845,3846],{"class":536}," -i\n",[980,3848,3849],{},"html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}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 .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}",{"title":49,"searchDepth":533,"depth":533,"links":3851},[],"Resolve the issue of Freqtrade proxy configuration not taking effect. Fix network connection barriers by correctly setting ccxt_config and switching from the pip version to the Git version.",{"date":3854,"category":3662,"tags":3855,"order":522,"meta-description":3862,"meta-keyword":3863},"2026-04-06",[3664,3856,3857,3858,3859,3860,3861],"Proxy","CCXT","Python","Git","Bug Fix","Trading","Learn how to fix Freqtrade proxy not working. Master the correct ccxt_config format, and discover why uninstalling the pip version and using Git pull resolves proxy connection failures.","Freqtrade, proxy, ccxt_config, Freqtrade proxy not working, trading bot, proxy settings, Python","/en/blog/freqtrade-proxy-not-working",{"title":3679,"description":3852},"en/blog/freqtrade-proxy-not-working","EBzdnEbaW8l6CvPJuArmzWRJ6WwaU3wZucoyqL8jefo",{"id":3869,"title":3870,"body":3871,"description":5061,"extension":1026,"meta":5062,"navigation":1039,"path":5070,"seo":5071,"stem":5072,"__hash__":5073},"en/en/blog/frontend-component-library-recommendation.md","Best Frontend Component Libraries in 2025: React, Vue3, and Angular",{"type":8,"value":3872,"toc":5055},[3873,3878,3903,3907,3917,4300,4304,4313,4807,4811,4814,4991,4995,5011,5045],[3874,3875,3877],"h1",{"id":3876},"best-frontend-component-libraries-in-2025","Best Frontend Component Libraries in 2025",[11,3879,3880,3881,3884,3885,3888,3889,774,3892,3895,3896,3899,3900,390],{},"In ",[21,3882,3883],{},"2025",", the frontend ecosystem continues to evolve rapidly. Choosing the right ",[21,3886,3887],{},"UI component library"," can greatly accelerate development, improve design consistency, and enhance user experience. This article summarizes the most popular and reliable component libraries across ",[21,3890,3891],{},"React",[21,3893,3894],{},"Vue3",", and ",[21,3897,3898],{},"Angular",", along with their GitHub stars as of ",[21,3901,3902],{},"August 2025",[35,3904,3906],{"id":3905},"react-component-libraries","React Component Libraries",[11,3908,3909,3910,788,3913,3916],{},"React remains the most widely used frontend framework, and its ecosystem offers mature and modern UI libraries for both ",[21,3911,3912],{},"PC",[21,3914,3915],{},"mobile"," platforms.",[79,3918,3919,3940],{},[82,3920,3921],{},[85,3922,3923,3927,3931,3934,3937],{},[88,3924,3926],{"align":3925},"left","Component Library",[88,3928,3930],{"align":3929},"center","Mobile/PC",[88,3932,3933],{"align":3925},"Website",[88,3935,3936],{"align":3925},"GitHub",[88,3938,3939],{"align":3925},"Stars",[104,3941,3942,3966,3990,4014,4038,4062,4086,4111,4135,4159,4183,4207,4231,4254,4277],{},[85,3943,3944,3947,3949,3956,3963],{},[109,3945,3946],{"align":3925},"Material UI",[109,3948,3912],{"align":3929},[109,3950,3951],{"align":3925},[371,3952,3955],{"href":3953,"rel":3954},"https://mui.com/",[388],"mui.com",[109,3957,3958],{"align":3925},[371,3959,3962],{"href":3960,"rel":3961},"https://github.com/mui/material-ui",[388],"material-ui",[109,3964,3965],{"align":3925},"96.3K",[85,3967,3968,3971,3973,3980,3987],{},[109,3969,3970],{"align":3925},"Ant Design",[109,3972,3912],{"align":3929},[109,3974,3975],{"align":3925},[371,3976,3979],{"href":3977,"rel":3978},"https://ant.design/",[388],"ant.design",[109,3981,3982],{"align":3925},[371,3983,3986],{"href":3984,"rel":3985},"https://github.com/ant-design/ant-design",[388],"ant-design",[109,3988,3989],{"align":3925},"95.6K",[85,3991,3992,3995,3997,4004,4011],{},[109,3993,3994],{"align":3925},"Shadcn UI",[109,3996,3912],{"align":3929},[109,3998,3999],{"align":3925},[371,4000,4003],{"href":4001,"rel":4002},"https://ui.shadcn.com/",[388],"ui.shadcn.com",[109,4005,4006],{"align":3925},[371,4007,4010],{"href":4008,"rel":4009},"https://github.com/shadcn-ui/ui",[388],"shadcn-ui",[109,4012,4013],{"align":3925},"92.7K",[85,4015,4016,4019,4021,4028,4035],{},[109,4017,4018],{"align":3925},"Chakra UI",[109,4020,3912],{"align":3929},[109,4022,4023],{"align":3925},[371,4024,4027],{"href":4025,"rel":4026},"https://chakra-ui.com/",[388],"chakra-ui.com",[109,4029,4030],{"align":3925},[371,4031,4034],{"href":4032,"rel":4033},"https://github.com/chakra-ui/chakra-ui",[388],"chakra-ui",[109,4036,4037],{"align":3925},"39.5K",[85,4039,4040,4043,4045,4052,4059],{},[109,4041,4042],{"align":3925},"Mantine",[109,4044,3912],{"align":3929},[109,4046,4047],{"align":3925},[371,4048,4051],{"href":4049,"rel":4050},"https://mantine.dev/",[388],"mantine.dev",[109,4053,4054],{"align":3925},[371,4055,4058],{"href":4056,"rel":4057},"https://github.com/mantinedev/mantine",[388],"mantine",[109,4060,4061],{"align":3925},"29.4K",[85,4063,4064,4067,4069,4076,4083],{},[109,4065,4066],{"align":3925},"React Bootstrap",[109,4068,3912],{"align":3929},[109,4070,4071],{"align":3925},[371,4072,4075],{"href":4073,"rel":4074},"https://react-bootstrap.github.io/",[388],"react-bootstrap.github.io",[109,4077,4078],{"align":3925},[371,4079,4082],{"href":4080,"rel":4081},"https://github.com/react-bootstrap/react-bootstrap",[388],"react-bootstrap",[109,4084,4085],{"align":3925},"22.6K",[85,4087,4088,4091,4094,4101,4108],{},[109,4089,4090],{"align":3925},"Fluent UI",[109,4092,4093],{"align":3929},"PC/Mobile",[109,4095,4096],{"align":3925},[371,4097,4100],{"href":4098,"rel":4099},"https://react.fluentui.dev/",[388],"react.fluentui.dev",[109,4102,4103],{"align":3925},[371,4104,4107],{"href":4105,"rel":4106},"https://github.com/microsoft/fluentui",[388],"fluentui",[109,4109,4110],{"align":3925},"19.5K",[85,4112,4113,4116,4118,4125,4132],{},[109,4114,4115],{"align":3925},"Semantic UI React",[109,4117,3912],{"align":3929},[109,4119,4120],{"align":3925},[371,4121,4124],{"href":4122,"rel":4123},"https://react.semantic-ui.com/",[388],"semantic-ui",[109,4126,4127],{"align":3925},[371,4128,4131],{"href":4129,"rel":4130},"https://github.com/Semantic-Org/Semantic-UI-React",[388],"Semantic-UI-React",[109,4133,4134],{"align":3925},"13.3K",[85,4136,4137,4140,4142,4149,4156],{},[109,4138,4139],{"align":3925},"Semi Design",[109,4141,3912],{"align":3929},[109,4143,4144],{"align":3925},[371,4145,4148],{"href":4146,"rel":4147},"https://semi.design/",[388],"semi.design",[109,4150,4151],{"align":3925},[371,4152,4155],{"href":4153,"rel":4154},"https://github.com/DouyinFE/semi-design",[388],"semi-design",[109,4157,4158],{"align":3925},"9.3K",[85,4160,4161,4164,4167,4174,4180],{},[109,4162,4163],{"align":3925},"OnsenUI",[109,4165,4166],{"align":3929},"Mobile",[109,4168,4169],{"align":3925},[371,4170,4173],{"href":4171,"rel":4172},"https://onsen.io/",[388],"onsen.io",[109,4175,4176],{"align":3925},[371,4177,4163],{"href":4178,"rel":4179},"https://github.com/OnsenUI/OnsenUI",[388],[109,4181,4182],{"align":3925},"8.9K",[85,4184,4185,4188,4190,4197,4204],{},[109,4186,4187],{"align":3925},"PrimeReact",[109,4189,3912],{"align":3929},[109,4191,4192],{"align":3925},[371,4193,4196],{"href":4194,"rel":4195},"https://primereact.org/",[388],"primereact.org",[109,4198,4199],{"align":3925},[371,4200,4203],{"href":4201,"rel":4202},"https://github.com/primefaces/primereact",[388],"primereact",[109,4205,4206],{"align":3925},"7.9K",[85,4208,4209,4212,4214,4221,4228],{},[109,4210,4211],{"align":3925},"TDesign",[109,4213,4093],{"align":3929},[109,4215,4216],{"align":3925},[371,4217,4220],{"href":4218,"rel":4219},"https://tdesign.tencent.com/",[388],"tdesign.tencent.com",[109,4222,4223],{"align":3925},[371,4224,4227],{"href":4225,"rel":4226},"https://github.com/Tencent/tdesign",[388],"tdesign",[109,4229,4230],{"align":3925},"3.5K",[85,4232,4233,4236,4238,4245,4251],{},[109,4234,4235],{"align":3925},"Quark Design",[109,4237,4166],{"align":3929},[109,4239,4240],{"align":3925},[371,4241,4244],{"href":4242,"rel":4243},"https://quark-ecosystem.github.io/quarkd-docs",[388],"quark-design",[109,4246,4247],{"align":3925},[371,4248,4244],{"href":4249,"rel":4250},"https://github.com/hellof2e/quark-design",[388],[109,4252,4253],{"align":3925},"1.9K",[85,4255,4256,4259,4261,4268,4274],{},[109,4257,4258],{"align":3925},"NutUI React",[109,4260,4166],{"align":3929},[109,4262,4263],{"align":3925},[371,4264,4267],{"href":4265,"rel":4266},"https://nutui.jd.com/react/",[388],"nutui-react",[109,4269,4270],{"align":3925},[371,4271,4267],{"href":4272,"rel":4273},"https://github.com/jdf2e/nutui-react",[388],[109,4275,4276],{"align":3925},"1.1K",[85,4278,4279,4282,4284,4291,4297],{},[109,4280,4281],{"align":3925},"HiUI",[109,4283,3912],{"align":3929},[109,4285,4286],{"align":3925},[371,4287,4290],{"href":4288,"rel":4289},"https://xiaomi.github.io/hiui/",[388],"hiui",[109,4292,4293],{"align":3925},[371,4294,4290],{"href":4295,"rel":4296},"https://github.com/XiaoMi/hiui",[388],[109,4298,4299],{"align":3925},"827",[35,4301,4303],{"id":4302},"vue3-component-libraries","Vue3 Component Libraries",[11,4305,4306,4307,788,4310,4312],{},"Vue3 has gained widespread adoption, with a strong set of libraries for ",[21,4308,4309],{},"desktop",[21,4311,3915],{}," development.",[79,4314,4315,4329],{},[82,4316,4317],{},[85,4318,4319,4321,4323,4325,4327],{},[88,4320,3926],{"align":3925},[88,4322,3930],{"align":3925},[88,4324,3933],{"align":3925},[88,4326,3936],{"align":3925},[88,4328,3939],{"align":3925},[104,4330,4331,4355,4379,4403,4427,4451,4475,4499,4523,4541,4564,4588,4612,4634,4652,4670,4694,4717,4741,4765,4788],{},[85,4332,4333,4336,4338,4345,4352],{},[109,4334,4335],{"align":3925},"Vuetify",[109,4337,3912],{"align":3925},[109,4339,4340],{"align":3925},[371,4341,4344],{"href":4342,"rel":4343},"https://vuetifyjs.com/",[388],"vuetifyjs.com",[109,4346,4347],{"align":3925},[371,4348,4351],{"href":4349,"rel":4350},"https://github.com/vuetifyjs/vuetify",[388],"vuetify",[109,4353,4354],{"align":3925},"40.7K",[85,4356,4357,4360,4362,4369,4376],{},[109,4358,4359],{"align":3925},"Quasar",[109,4361,3930],{"align":3925},[109,4363,4364],{"align":3925},[371,4365,4368],{"href":4366,"rel":4367},"https://quasar.dev/",[388],"quasar.dev",[109,4370,4371],{"align":3925},[371,4372,4375],{"href":4373,"rel":4374},"https://github.com/quasarframework/quasar",[388],"quasar",[109,4377,4378],{"align":3925},"26.8K",[85,4380,4381,4384,4386,4393,4400],{},[109,4382,4383],{"align":3925},"Vant",[109,4385,4166],{"align":3925},[109,4387,4388],{"align":3925},[371,4389,4392],{"href":4390,"rel":4391},"https://vant.pro/vant/",[388],"vant.pro",[109,4394,4395],{"align":3925},[371,4396,4399],{"href":4397,"rel":4398},"https://github.com/youzan/vant",[388],"vant",[109,4401,4402],{"align":3925},"24K",[85,4404,4405,4408,4410,4417,4424],{},[109,4406,4407],{"align":3925},"Ant Design Vue",[109,4409,3912],{"align":3925},[109,4411,4412],{"align":3925},[371,4413,4416],{"href":4414,"rel":4415},"https://antdv.com/",[388],"antdv.com",[109,4418,4419],{"align":3925},[371,4420,4423],{"href":4421,"rel":4422},"https://github.com/vueComponent/ant-design-vue",[388],"ant-design-vue",[109,4425,4426],{"align":3925},"21K",[85,4428,4429,4432,4434,4441,4448],{},[109,4430,4431],{"align":3925},"Naive UI",[109,4433,3912],{"align":3925},[109,4435,4436],{"align":3925},[371,4437,4440],{"href":4438,"rel":4439},"https://www.naiveui.com/",[388],"naiveui.com",[109,4442,4443],{"align":3925},[371,4444,4447],{"href":4445,"rel":4446},"https://github.com/tusen-ai/naive-ui",[388],"naive-ui",[109,4449,4450],{"align":3925},"17.5K",[85,4452,4453,4456,4458,4465,4472],{},[109,4454,4455],{"align":3925},"BootstrapVue",[109,4457,3912],{"align":3925},[109,4459,4460],{"align":3925},[371,4461,4464],{"href":4462,"rel":4463},"https://bootstrap-vue.org/",[388],"bootstrap-vue.org",[109,4466,4467],{"align":3925},[371,4468,4471],{"href":4469,"rel":4470},"https://github.com/bootstrap-vue/bootstrap-vue",[388],"bootstrap-vue",[109,4473,4474],{"align":3925},"14.5K",[85,4476,4477,4480,4482,4489,4496],{},[109,4478,4479],{"align":3925},"PrimeVue",[109,4481,3912],{"align":3925},[109,4483,4484],{"align":3925},[371,4485,4488],{"href":4486,"rel":4487},"https://primevue.org/",[388],"primevue.org",[109,4490,4491],{"align":3925},[371,4492,4495],{"href":4493,"rel":4494},"https://github.com/primefaces/primevue",[388],"primevue",[109,4497,4498],{"align":3925},"13.2K",[85,4500,4501,4504,4506,4513,4520],{},[109,4502,4503],{"align":3925},"Buefy",[109,4505,3912],{"align":3925},[109,4507,4508],{"align":3925},[371,4509,4512],{"href":4510,"rel":4511},"https://buefy.org/",[388],"buefy.org",[109,4514,4515],{"align":3925},[371,4516,4519],{"href":4517,"rel":4518},"https://github.com/buefy/buefy",[388],"buefy",[109,4521,4522],{"align":3925},"9.6K",[85,4524,4525,4527,4529,4534,4539],{},[109,4526,4163],{"align":3925},[109,4528,4166],{"align":3925},[109,4530,4531],{"align":3925},[371,4532,4173],{"href":4171,"rel":4533},[388],[109,4535,4536],{"align":3925},[371,4537,4163],{"href":4178,"rel":4538},[388],[109,4540,4182],{"align":3925},[85,4542,4543,4546,4548,4555,4561],{},[109,4544,4545],{"align":3925},"NutUI",[109,4547,4166],{"align":3925},[109,4549,4550],{"align":3925},[371,4551,4554],{"href":4552,"rel":4553},"https://nutui.jd.com/",[388],"nutui",[109,4556,4557],{"align":3925},[371,4558,4554],{"href":4559,"rel":4560},"https://github.com/jd-opensource/nutui",[388],[109,4562,4563],{"align":3925},"6.4K",[85,4565,4566,4569,4571,4578,4585],{},[109,4567,4568],{"align":3925},"Varlet",[109,4570,4166],{"align":3925},[109,4572,4573],{"align":3925},[371,4574,4577],{"href":4575,"rel":4576},"https://varletjs.org/#/en-US/home",[388],"varletjs.org",[109,4579,4580],{"align":3925},[371,4581,4584],{"href":4582,"rel":4583},"https://github.com/varletjs/varlet",[388],"varlet",[109,4586,4587],{"align":3925},"5.2K",[85,4589,4590,4593,4595,4602,4609],{},[109,4591,4592],{"align":3925},"Inspira UI",[109,4594,3912],{"align":3925},[109,4596,4597],{"align":3925},[371,4598,4601],{"href":4599,"rel":4600},"https://inspira-ui.com/docs/getting-started/introduction",[388],"inspira-ui.com",[109,4603,4604],{"align":3925},[371,4605,4608],{"href":4606,"rel":4607},"https://github.com/unovue/inspira-ui",[388],"inspira-ui",[109,4610,4611],{"align":3925},"3.6K",[85,4613,4614,4617,4619,4626,4632],{},[109,4615,4616],{"align":3925},"Vuestic UI",[109,4618,3912],{"align":3925},[109,4620,4621],{"align":3925},[371,4622,4625],{"href":4623,"rel":4624},"https://ui.vuestic.dev/",[388],"vuestic-ui",[109,4627,4628],{"align":3925},[371,4629,4625],{"href":4630,"rel":4631},"https://github.com/epicmaxco/vuestic-ui",[388],[109,4633,4611],{"align":3925},[85,4635,4636,4638,4640,4645,4650],{},[109,4637,4211],{"align":3925},[109,4639,4093],{"align":3925},[109,4641,4642],{"align":3925},[371,4643,4220],{"href":4218,"rel":4644},[388],[109,4646,4647],{"align":3925},[371,4648,4227],{"href":4225,"rel":4649},[388],[109,4651,4230],{"align":3925},[85,4653,4654,4656,4658,4663,4668],{},[109,4655,4235],{"align":3925},[109,4657,4166],{"align":3925},[109,4659,4660],{"align":3925},[371,4661,4244],{"href":4242,"rel":4662},[388],[109,4664,4665],{"align":3925},[371,4666,4244],{"href":4249,"rel":4667},[388],[109,4669,4253],{"align":3925},[85,4671,4672,4675,4677,4684,4691],{},[109,4673,4674],{"align":3925},"Zarm",[109,4676,4166],{"align":3925},[109,4678,4679],{"align":3925},[371,4680,4683],{"href":4681,"rel":4682},"https://zarm.design/#/",[388],"zarm.design",[109,4685,4686],{"align":3925},[371,4687,4690],{"href":4688,"rel":4689},"https://github.com/ZhongAnTech/zarm",[388],"zarm",[109,4692,4693],{"align":3925},"1.7K",[85,4695,4696,4699,4701,4708,4715],{},[109,4697,4698],{"align":3925},"VEUI",[109,4700,3912],{"align":3925},[109,4702,4703],{"align":3925},[371,4704,4707],{"href":4705,"rel":4706},"https://veui.dev/",[388],"veui.dev",[109,4709,4710],{"align":3925},[371,4711,4714],{"href":4712,"rel":4713},"https://github.com/ecomfe/veui",[388],"veui",[109,4716,4276],{"align":3925},[85,4718,4719,4722,4724,4731,4738],{},[109,4720,4721],{"align":3925},"Flowbite Vue",[109,4723,3912],{"align":3925},[109,4725,4726],{"align":3925},[371,4727,4730],{"href":4728,"rel":4729},"https://flowbite-vue.com/",[388],"flowbite-vue.com",[109,4732,4733],{"align":3925},[371,4734,4737],{"href":4735,"rel":4736},"https://github.com/themesberg/flowbite-vue",[388],"flowbite-vue",[109,4739,4740],{"align":3925},"888",[85,4742,4743,4746,4748,4755,4762],{},[109,4744,4745],{"align":3925},"Inkline",[109,4747,3912],{"align":3925},[109,4749,4750],{"align":3925},[371,4751,4754],{"href":4752,"rel":4753},"https://www.inkline.io/",[388],"inkline.io",[109,4756,4757],{"align":3925},[371,4758,4761],{"href":4759,"rel":4760},"https://github.com/inkline/inkline",[388],"inkline",[109,4763,4764],{"align":3925},"1.4K",[85,4766,4767,4770,4772,4779,4785],{},[109,4768,4769],{"align":3925},"Balm UI",[109,4771,3912],{"align":3925},[109,4773,4774],{"align":3925},[371,4775,4778],{"href":4776,"rel":4777},"https://material.balmjs.com/",[388],"balm-ui",[109,4780,4781],{"align":3925},[371,4782,4778],{"href":4783,"rel":4784},"https://github.com/balmjs/balm-ui",[388],[109,4786,4787],{"align":3925},"510",[85,4789,4790,4793,4795,4802,4805],{},[109,4791,4792],{"align":3925},"Ionic Vue",[109,4794,4166],{"align":3925},[109,4796,4797],{"align":3925},[371,4798,4801],{"href":4799,"rel":4800},"https://ionic.nodejs.cn/",[388],"ionic",[109,4803,4804],{"align":3925},"–",[109,4806,4804],{"align":3925},[35,4808,4810],{"id":4809},"angular-component-libraries","Angular Component Libraries",[11,4812,4813],{},"Angular still plays a major role in enterprise applications, supported by well-maintained UI kits.",[79,4815,4816,4830],{},[82,4817,4818],{},[85,4819,4820,4822,4824,4826,4828],{},[88,4821,3926],{"align":3925},[88,4823,3930],{"align":3925},[88,4825,3933],{"align":3925},[88,4827,3936],{"align":3925},[88,4829,3939],{"align":3925},[104,4831,4832,4856,4880,4904,4927,4949,4967],{},[85,4833,4834,4837,4839,4846,4853],{},[109,4835,4836],{"align":3925},"Angular Material",[109,4838,3912],{"align":3925},[109,4840,4841],{"align":3925},[371,4842,4845],{"href":4843,"rel":4844},"https://material.angular.dev/",[388],"material.angular.dev",[109,4847,4848],{"align":3925},[371,4849,4852],{"href":4850,"rel":4851},"https://github.com/angular/components",[388],"angular/components",[109,4854,4855],{"align":3925},"24.8K",[85,4857,4858,4861,4863,4870,4877],{},[109,4859,4860],{"align":3925},"PrimeNG",[109,4862,3912],{"align":3925},[109,4864,4865],{"align":3925},[371,4866,4869],{"href":4867,"rel":4868},"https://primeng.org/",[388],"primeng.org",[109,4871,4872],{"align":3925},[371,4873,4876],{"href":4874,"rel":4875},"https://github.com/primefaces/primeng",[388],"primeng",[109,4878,4879],{"align":3925},"11.9K",[85,4881,4882,4885,4887,4894,4901],{},[109,4883,4884],{"align":3925},"NG-ZORRO",[109,4886,3912],{"align":3925},[109,4888,4889],{"align":3925},[371,4890,4893],{"href":4891,"rel":4892},"https://ng.ant.design",[388],"ng.ant.design",[109,4895,4896],{"align":3925},[371,4897,4900],{"href":4898,"rel":4899},"https://github.com/NG-ZORRO/ng-zorro-antd",[388],"ng-zorro-antd",[109,4902,4903],{"align":3925},"9.1K",[85,4905,4906,4909,4911,4918,4924],{},[109,4907,4908],{"align":3925},"Nebular",[109,4910,3912],{"align":3925},[109,4912,4913],{"align":3925},[371,4914,4917],{"href":4915,"rel":4916},"https://akveo.github.io/nebular/",[388],"nebular",[109,4919,4920],{"align":3925},[371,4921,4917],{"href":4922,"rel":4923},"https://github.com/akveo/nebular",[388],[109,4925,4926],{"align":3925},"8.1K",[85,4928,4929,4932,4934,4940,4946],{},[109,4930,4931],{"align":3925},"ng-bootstrap",[109,4933,4093],{"align":3925},[109,4935,4936],{"align":3925},[371,4937,4931],{"href":4938,"rel":4939},"https://ng-bootstrap.github.io/#/home",[388],[109,4941,4942],{"align":3925},[371,4943,4931],{"href":4944,"rel":4945},"https://github.com/ng-bootstrap/ng-bootstrap",[388],[109,4947,4948],{"align":3925},"8.3K",[85,4950,4951,4954,4956,4963,4965],{},[109,4952,4953],{"align":3925},"Clarity",[109,4955,3912],{"align":3925},[109,4957,4958],{"align":3925},[371,4959,4962],{"href":4960,"rel":4961},"https://clarity.design/",[388],"clarity.design",[109,4964,4804],{"align":3925},[109,4966,4804],{"align":3925},[85,4968,4969,4972,4974,4981,4988],{},[109,4970,4971],{"align":3925},"Taiga UI",[109,4973,3912],{"align":3925},[109,4975,4976],{"align":3925},[371,4977,4980],{"href":4978,"rel":4979},"https://taiga-ui.dev/",[388],"taiga-ui.dev",[109,4982,4983],{"align":3925},[371,4984,4987],{"href":4985,"rel":4986},"https://github.com/taiga-family/taiga-ui",[388],"taiga-ui",[109,4989,4990],{"align":3925},"3.7K",[35,4992,4994],{"id":4993},"conclusion","Conclusion",[11,4996,3880,4997,4999,5000,774,5002,778,5004,5006,5007,5010],{},[21,4998,3883],{},", whether you are working with ",[21,5001,3891],{},[21,5003,3894],{},[21,5005,3898],{},", there is a wide variety of ",[21,5008,5009],{},"frontend UI libraries"," to choose from.",[15,5012,5013,5025,5036],{},[18,5014,5015,5016,5018,5019,774,5021,3895,5023,390],{},"For ",[21,5017,3891],{},", the leaders remain ",[21,5020,3946],{},[21,5022,3970],{},[21,5024,3994],{},[18,5026,5015,5027,774,5029,774,5031,3895,5033,5035],{},[21,5028,3894],{},[21,5030,4335],{},[21,5032,4359],{},[21,5034,4383],{}," stand out.",[18,5037,5015,5038,774,5040,788,5042,5044],{},[21,5039,3898],{},[21,5041,4836],{},[21,5043,4860],{}," dominate the ecosystem.",[11,5046,5047,5048,5051,5052,390],{},"Selecting the right ",[21,5049,5050],{},"component library"," depends on your ",[21,5053,5054],{},"project scale, design requirements, and ecosystem preference",{"title":49,"searchDepth":533,"depth":533,"links":5056},[5057,5058,5059,5060],{"id":3905,"depth":533,"text":3906},{"id":4302,"depth":533,"text":4303},{"id":4809,"depth":533,"text":4810},{"id":4993,"depth":533,"text":4994},"A comprehensive guide to the most popular frontend component libraries in 2025, including React, Vue3, and Angular ecosystems. Updated with GitHub stars and official websites.",{"date":5063,"category":5064,"tags":5065,"order":522,"meta-description":5068,"meta-keyword":5069},"2025-08-08","Frontend",[3891,3894,3898,5064,5066,5067,3883],"UI Components","JavaScript Frameworks","Explore the best frontend component libraries in 2025. Covering React, Vue3, and Angular with updated GitHub stars, websites, and recommendations for developers.","React component library 2025, Vue3 UI frameworks, Angular components, frontend libraries, UI kits, JavaScript UI components, best frontend libraries","/en/blog/frontend-component-library-recommendation",{"title":3870,"description":5061},"en/blog/frontend-component-library-recommendation","LL0hLtAw_MUR-tREuUqyMhM73Pv24Xr1i3-W6A7-aEg",{"id":5075,"title":5076,"body":5077,"description":6733,"extension":1026,"meta":6734,"navigation":1039,"path":6746,"seo":6747,"stem":6748,"__hash__":6749},"en/en/blog/json-ld.md","Comprehensive Guide to JSON-LD for SEO and Web Data Structuring",{"type":8,"value":5078,"toc":6713},[5079,5083,5086,5090,5116,5119,5123,5126,5184,5208,5211,5215,5277,5281,5285,5335,5339,5409,5415,5469,5476,5480,5483,5488,5594,5599,5779,5783,5786,5882,5885,5892,5897,5902,6143,6147,6173,6177,6189,6195,6201,6217,6223,6227,6232,6399,6403,6521,6525,6683,6687,6710],[35,5080,5082],{"id":5081},"what-is-json-ld","What is JSON-LD?",[11,5084,5085],{},"JSON-LD (JavaScript Object Notation for Linked Data) is a lightweight, JSON-based format designed to embed machine-readable metadata into web pages. It enables search engines and applications to better understand your page content by providing semantic markup using the widely adopted Schema.org vocabulary. This enhanced understanding boosts SEO performance, supports rich results (like ratings, pricing, and events), and facilitates technologies such as voice search and AI assistants.",[35,5087,5089],{"id":5088},"core-features-of-json-ld","Core Features of JSON-LD",[15,5091,5092,5098,5104,5110],{},[18,5093,5094,5097],{},[21,5095,5096],{},"JSON Syntax:"," Simple and human-readable.",[18,5099,5100,5103],{},[21,5101,5102],{},"Semantic Markup:"," Uses Schema.org vocabularies to clearly define content meaning.",[18,5105,5106,5109],{},[21,5107,5108],{},"Flexibility:"," Supports nested objects, arrays, and multilingual text.",[18,5111,5112,5115],{},[21,5113,5114],{},"Wide Application:"," Applicable for SEO, voice search, data integration, and more.",[11,5117,5118],{},"Search engines primarily parse HTML and text but cannot inherently grasp the meaning of content. JSON-LD bridges this gap by explicitly labeling content types such as Product, Person, FAQPage, which helps engines better match user queries and display rich snippets.",[35,5120,5122],{"id":5121},"basic-syntax-of-json-ld","Basic Syntax of JSON-LD",[11,5124,5125],{},"A typical JSON-LD block includes:",[43,5127,5129],{"className":1355,"code":5128,"language":1357,"meta":49,"style":49},"\u003Cscript type=\"application/ld+json\">\n{\n  \"@context\": \"https://schema.org\",\n  \"@type\": \"Product\",\n  \"name\": \"Example Product\",\n  \"description\": \"A description of the example product.\"\n}\n\u003C/script>\n",[51,5130,5131,5148,5152,5157,5162,5167,5172,5176],{"__ignoreMap":49},[519,5132,5133,5135,5138,5141,5143,5146],{"class":521,"line":522},[519,5134,1364],{"class":529},[519,5136,5137],{"class":1367},"script",[519,5139,5140],{"class":525}," type",[519,5142,1376],{"class":529},[519,5144,5145],{"class":1379},"\"application/ld+json\"",[519,5147,1460],{"class":529},[519,5149,5150],{"class":521,"line":533},[519,5151,2599],{"class":529},[519,5153,5154],{"class":521,"line":553},[519,5155,5156],{"class":529},"  \"@context\": \"https://schema.org\",\n",[519,5158,5159],{"class":521,"line":566},[519,5160,5161],{"class":529},"  \"@type\": \"Product\",\n",[519,5163,5164],{"class":521,"line":578},[519,5165,5166],{"class":529},"  \"name\": \"Example Product\",\n",[519,5168,5169],{"class":521,"line":591},[519,5170,5171],{"class":529},"  \"description\": \"A description of the example product.\"\n",[519,5173,5174],{"class":521,"line":1408},[519,5175,594],{"class":529},[519,5177,5178,5180,5182],{"class":521,"line":1414},[519,5179,1592],{"class":529},[519,5181,5137],{"class":1367},[519,5183,1460],{"class":529},[15,5185,5186,5192,5198],{},[18,5187,5188,5191],{},[51,5189,5190],{},"@context",": Defines the vocabulary (usually Schema.org).",[18,5193,5194,5197],{},[51,5195,5196],{},"@type",": Specifies the data type (e.g., Product, Event).",[18,5199,5200,5201,774,5204,5207],{},"Properties such as ",[51,5202,5203],{},"name",[51,5205,5206],{},"description"," provide details.",[11,5209,5210],{},"This data is embedded in your webpage’s HTML but not visible to users. It informs search engines about the page content semantics.",[35,5212,5214],{"id":5213},"important-json-ld-keywords","Important JSON-LD Keywords",[79,5216,5217,5227],{},[82,5218,5219],{},[85,5220,5221,5224],{},[88,5222,5223],{},"Keyword",[88,5225,5226],{},"Description",[104,5228,5229,5238,5247,5257,5267],{},[85,5230,5231,5235],{},[109,5232,5233],{},[51,5234,5190],{},[109,5236,5237],{},"Vocabulary and rules used (e.g., Schema.org)",[85,5239,5240,5244],{},[109,5241,5242],{},[51,5243,5196],{},[109,5245,5246],{},"Defines the entity type (Product, Event, etc.)",[85,5248,5249,5254],{},[109,5250,5251],{},[51,5252,5253],{},"@id",[109,5255,5256],{},"Unique identifier (optional)",[85,5258,5259,5264],{},[109,5260,5261],{},[51,5262,5263],{},"@value",[109,5265,5266],{},"Literal value of a property",[85,5268,5269,5274],{},[109,5270,5271],{},[51,5272,5273],{},"@language",[109,5275,5276],{},"Specifies language of text (e.g., \"en\")",[35,5278,5280],{"id":5279},"common-json-ld-types","Common JSON-LD Types",[153,5282,5284],{"id":5283},"core-types","Core Types",[15,5286,5287,5293,5299,5305,5311,5317,5323,5329],{},[18,5288,5289,5292],{},[21,5290,5291],{},"Thing",": Base type for all entities.",[18,5294,5295,5298],{},[21,5296,5297],{},"CreativeWork",": Articles, books, movies, music.",[18,5300,5301,5304],{},[21,5302,5303],{},"Event",": Concerts, conferences, sports.",[18,5306,5307,5310],{},[21,5308,5309],{},"Organization",": Companies, schools, nonprofits.",[18,5312,5313,5316],{},[21,5314,5315],{},"Person",": Individuals.",[18,5318,5319,5322],{},[21,5320,5321],{},"Place",": Locations, businesses.",[18,5324,5325,5328],{},[21,5326,5327],{},"Product",": Items or services.",[18,5330,5331,5334],{},[21,5332,5333],{},"Action",": User actions like purchases or reviews.",[153,5336,5338],{"id":5337},"frequently-used-subtypes","Frequently Used Subtypes",[79,5340,5341,5351],{},[82,5342,5343],{},[85,5344,5345,5348],{},[88,5346,5347],{},"Category",[88,5349,5350],{},"Example Types",[104,5352,5353,5361,5369,5377,5385,5393,5401],{},[85,5354,5355,5358],{},[109,5356,5357],{},"Articles",[109,5359,5360],{},"BlogPosting, NewsArticle, TechArticle",[85,5362,5363,5366],{},[109,5364,5365],{},"Organizations",[109,5367,5368],{},"Corporation, NGO, LocalBusiness",[85,5370,5371,5374],{},[109,5372,5373],{},"Local Businesses",[109,5375,5376],{},"Restaurant, Hotel, TouristAttraction",[85,5378,5379,5382],{},[109,5380,5381],{},"Media & Entertainment",[109,5383,5384],{},"Movie, TVSeries, MusicAlbum",[85,5386,5387,5390],{},[109,5388,5389],{},"E-commerce",[109,5391,5392],{},"Product, Offer, Review, Brand",[85,5394,5395,5398],{},[109,5396,5397],{},"Events",[109,5399,5400],{},"Festival, SportsEvent, MusicEvent",[85,5402,5403,5406],{},[109,5404,5405],{},"SEO Support",[109,5407,5408],{},"FAQPage, BreadcrumbList, HowTo",[35,5410,5412,5413],{"id":5411},"choosing-correct-type","Choosing Correct ",[51,5414,5196],{},[15,5416,5417,5423,5429,5434,5440,5446,5451,5457,5463],{},[18,5418,5419,5420],{},"Blog post → ",[51,5421,5422],{},"BlogPosting",[18,5424,5425,5426],{},"News article → ",[51,5427,5428],{},"NewsArticle",[18,5430,5431,5432],{},"Product → ",[51,5433,5327],{},[18,5435,5436,5437],{},"FAQ page → ",[51,5438,5439],{},"FAQPage",[18,5441,5442,5443],{},"Local business → ",[51,5444,5445],{},"LocalBusiness",[18,5447,5448,5449],{},"Event → ",[51,5450,5303],{},[18,5452,5453,5454],{},"Review → ",[51,5455,5456],{},"Review",[18,5458,5459,5460],{},"Website → ",[51,5461,5462],{},"WebSite",[18,5464,5465,5466],{},"Web page → ",[51,5467,5468],{},"WebPage",[11,5470,5471,5472,5475],{},"You can combine multiple entities using ",[51,5473,5474],{},"@graph"," for complex pages.",[35,5477,5479],{"id":5478},"nested-structures-arrays","Nested Structures & Arrays",[11,5481,5482],{},"JSON-LD supports nested objects and arrays for complex relationships:",[11,5484,5485],{},[21,5486,5487],{},"Nested example: Product with offer",[43,5489,5491],{"className":2439,"code":5490,"language":2441,"meta":49,"style":49},"{\n  \"@context\": \"https://schema.org\",\n  \"@type\": \"Product\",\n  \"name\": \"Example Product\",\n  \"offers\": {\n    \"@type\": \"Offer\",\n    \"price\": \"99.99\",\n    \"priceCurrency\": \"USD\",\n    \"availability\": \"https://schema.org/InStock\"\n  }\n}\n",[51,5492,5493,5497,5509,5521,5533,5540,5552,5564,5576,5586,5590],{"__ignoreMap":49},[519,5494,5495],{"class":521,"line":522},[519,5496,2599],{"class":529},[519,5498,5499,5502,5504,5507],{"class":521,"line":533},[519,5500,5501],{"class":536},"  \"@context\"",[519,5503,540],{"class":529},[519,5505,5506],{"class":1379},"\"https://schema.org\"",[519,5508,2620],{"class":529},[519,5510,5511,5514,5516,5519],{"class":521,"line":553},[519,5512,5513],{"class":536},"  \"@type\"",[519,5515,540],{"class":529},[519,5517,5518],{"class":1379},"\"Product\"",[519,5520,2620],{"class":529},[519,5522,5523,5526,5528,5531],{"class":521,"line":566},[519,5524,5525],{"class":536},"  \"name\"",[519,5527,540],{"class":529},[519,5529,5530],{"class":1379},"\"Example Product\"",[519,5532,2620],{"class":529},[519,5534,5535,5538],{"class":521,"line":578},[519,5536,5537],{"class":536},"  \"offers\"",[519,5539,2607],{"class":529},[519,5541,5542,5545,5547,5550],{"class":521,"line":591},[519,5543,5544],{"class":536},"    \"@type\"",[519,5546,540],{"class":529},[519,5548,5549],{"class":1379},"\"Offer\"",[519,5551,2620],{"class":529},[519,5553,5554,5557,5559,5562],{"class":521,"line":1408},[519,5555,5556],{"class":536},"    \"price\"",[519,5558,540],{"class":529},[519,5560,5561],{"class":1379},"\"99.99\"",[519,5563,2620],{"class":529},[519,5565,5566,5569,5571,5574],{"class":521,"line":1414},[519,5567,5568],{"class":536},"    \"priceCurrency\"",[519,5570,540],{"class":529},[519,5572,5573],{"class":1379},"\"USD\"",[519,5575,2620],{"class":529},[519,5577,5578,5581,5583],{"class":521,"line":1425},[519,5579,5580],{"class":536},"    \"availability\"",[519,5582,540],{"class":529},[519,5584,5585],{"class":1379},"\"https://schema.org/InStock\"\n",[519,5587,5588],{"class":521,"line":1435},[519,5589,2726],{"class":529},[519,5591,5592],{"class":521,"line":1446},[519,5593,594],{"class":529},[11,5595,5596],{},[21,5597,5598],{},"Array example: FAQ with multiple questions",[43,5600,5602],{"className":2439,"code":5601,"language":2441,"meta":49,"style":49},"{\n  \"@context\": \"https://schema.org\",\n  \"@type\": \"FAQPage\",\n  \"mainEntity\": [\n    {\n      \"@type\": \"Question\",\n      \"name\": \"What is SEO?\",\n      \"acceptedAnswer\": {\n        \"@type\": \"Answer\",\n        \"text\": \"SEO optimizes site content and structure for better search rankings.\"\n      }\n    },\n    {\n      \"@type\": \"Question\",\n      \"name\": \"How to improve SEO?\",\n      \"acceptedAnswer\": {\n        \"@type\": \"Answer\",\n        \"text\": \"Improve site speed, content quality, keyword use, and backlinks.\"\n      }\n    }\n  ]\n}\n",[51,5603,5604,5608,5618,5629,5636,5641,5653,5665,5672,5684,5694,5699,5704,5708,5718,5730,5737,5748,5758,5763,5768,5774],{"__ignoreMap":49},[519,5605,5606],{"class":521,"line":522},[519,5607,2599],{"class":529},[519,5609,5610,5612,5614,5616],{"class":521,"line":533},[519,5611,5501],{"class":536},[519,5613,540],{"class":529},[519,5615,5506],{"class":1379},[519,5617,2620],{"class":529},[519,5619,5620,5622,5624,5627],{"class":521,"line":553},[519,5621,5513],{"class":536},[519,5623,540],{"class":529},[519,5625,5626],{"class":1379},"\"FAQPage\"",[519,5628,2620],{"class":529},[519,5630,5631,5634],{"class":521,"line":566},[519,5632,5633],{"class":536},"  \"mainEntity\"",[519,5635,3222],{"class":529},[519,5637,5638],{"class":521,"line":578},[519,5639,5640],{"class":529},"    {\n",[519,5642,5643,5646,5648,5651],{"class":521,"line":591},[519,5644,5645],{"class":536},"      \"@type\"",[519,5647,540],{"class":529},[519,5649,5650],{"class":1379},"\"Question\"",[519,5652,2620],{"class":529},[519,5654,5655,5658,5660,5663],{"class":521,"line":1408},[519,5656,5657],{"class":536},"      \"name\"",[519,5659,540],{"class":529},[519,5661,5662],{"class":1379},"\"What is SEO?\"",[519,5664,2620],{"class":529},[519,5666,5667,5670],{"class":521,"line":1414},[519,5668,5669],{"class":536},"      \"acceptedAnswer\"",[519,5671,2607],{"class":529},[519,5673,5674,5677,5679,5682],{"class":521,"line":1425},[519,5675,5676],{"class":536},"        \"@type\"",[519,5678,540],{"class":529},[519,5680,5681],{"class":1379},"\"Answer\"",[519,5683,2620],{"class":529},[519,5685,5686,5689,5691],{"class":521,"line":1435},[519,5687,5688],{"class":536},"        \"text\"",[519,5690,540],{"class":529},[519,5692,5693],{"class":1379},"\"SEO optimizes site content and structure for better search rankings.\"\n",[519,5695,5696],{"class":521,"line":1446},[519,5697,5698],{"class":529},"      }\n",[519,5700,5701],{"class":521,"line":1457},[519,5702,5703],{"class":529},"    },\n",[519,5705,5706],{"class":521,"line":1584},[519,5707,5640],{"class":529},[519,5709,5710,5712,5714,5716],{"class":521,"line":1589},[519,5711,5645],{"class":536},[519,5713,540],{"class":529},[519,5715,5650],{"class":1379},[519,5717,2620],{"class":529},[519,5719,5721,5723,5725,5728],{"class":521,"line":5720},15,[519,5722,5657],{"class":536},[519,5724,540],{"class":529},[519,5726,5727],{"class":1379},"\"How to improve SEO?\"",[519,5729,2620],{"class":529},[519,5731,5733,5735],{"class":521,"line":5732},16,[519,5734,5669],{"class":536},[519,5736,2607],{"class":529},[519,5738,5740,5742,5744,5746],{"class":521,"line":5739},17,[519,5741,5676],{"class":536},[519,5743,540],{"class":529},[519,5745,5681],{"class":1379},[519,5747,2620],{"class":529},[519,5749,5751,5753,5755],{"class":521,"line":5750},18,[519,5752,5688],{"class":536},[519,5754,540],{"class":529},[519,5756,5757],{"class":1379},"\"Improve site speed, content quality, keyword use, and backlinks.\"\n",[519,5759,5761],{"class":521,"line":5760},19,[519,5762,5698],{"class":529},[519,5764,5766],{"class":521,"line":5765},20,[519,5767,3782],{"class":529},[519,5769,5771],{"class":521,"line":5770},21,[519,5772,5773],{"class":529},"  ]\n",[519,5775,5777],{"class":521,"line":5776},22,[519,5778,594],{"class":529},[35,5780,5782],{"id":5781},"multilingual-support","Multilingual Support",[11,5784,5785],{},"You can specify language for text fields:",[43,5787,5789],{"className":2439,"code":5788,"language":2441,"meta":49,"style":49},"{\n  \"@context\": \"https://schema.org\",\n  \"@type\": \"Product\",\n  \"name\": {\n    \"@value\": \"示例产品\",\n    \"@language\": \"zh\"\n  },\n  \"description\": {\n    \"@value\": \"这是一个示例产品的描述。\",\n    \"@language\": \"zh\"\n  }\n}\n",[51,5790,5791,5795,5805,5815,5821,5833,5843,5848,5855,5866,5874,5878],{"__ignoreMap":49},[519,5792,5793],{"class":521,"line":522},[519,5794,2599],{"class":529},[519,5796,5797,5799,5801,5803],{"class":521,"line":533},[519,5798,5501],{"class":536},[519,5800,540],{"class":529},[519,5802,5506],{"class":1379},[519,5804,2620],{"class":529},[519,5806,5807,5809,5811,5813],{"class":521,"line":553},[519,5808,5513],{"class":536},[519,5810,540],{"class":529},[519,5812,5518],{"class":1379},[519,5814,2620],{"class":529},[519,5816,5817,5819],{"class":521,"line":566},[519,5818,5525],{"class":536},[519,5820,2607],{"class":529},[519,5822,5823,5826,5828,5831],{"class":521,"line":578},[519,5824,5825],{"class":536},"    \"@value\"",[519,5827,540],{"class":529},[519,5829,5830],{"class":1379},"\"示例产品\"",[519,5832,2620],{"class":529},[519,5834,5835,5838,5840],{"class":521,"line":591},[519,5836,5837],{"class":536},"    \"@language\"",[519,5839,540],{"class":529},[519,5841,5842],{"class":1379},"\"zh\"\n",[519,5844,5845],{"class":521,"line":1408},[519,5846,5847],{"class":529},"  },\n",[519,5849,5850,5853],{"class":521,"line":1414},[519,5851,5852],{"class":536},"  \"description\"",[519,5854,2607],{"class":529},[519,5856,5857,5859,5861,5864],{"class":521,"line":1425},[519,5858,5825],{"class":536},[519,5860,540],{"class":529},[519,5862,5863],{"class":1379},"\"这是一个示例产品的描述。\"",[519,5865,2620],{"class":529},[519,5867,5868,5870,5872],{"class":521,"line":1435},[519,5869,5837],{"class":536},[519,5871,540],{"class":529},[519,5873,5842],{"class":1379},[519,5875,5876],{"class":521,"line":1446},[519,5877,2726],{"class":529},[519,5879,5880],{"class":521,"line":1457},[519,5881,594],{"class":529},[11,5883,5884],{},"This enables simultaneous descriptions in multiple languages.",[35,5886,5888,5889,5891],{"id":5887},"the-graph-keyword","The ",[51,5890,5474],{}," Keyword",[11,5893,5894,5896],{},[51,5895,5474],{}," lets you bundle multiple related entities in one JSON-LD block, enhancing clarity and efficiency.",[11,5898,5899],{},[21,5900,5901],{},"Example combining product and review:",[43,5903,5905],{"className":2439,"code":5904,"language":2441,"meta":49,"style":49},"{\n  \"@context\": \"https://schema.org\",\n  \"@type\": \"WebPage\",\n  \"@graph\": [\n    {\n      \"@type\": \"Product\",\n      \"name\": \"High-Performance Wireless Headphones\",\n      \"price\": \"299.00\",\n      \"currency\": \"CNY\"\n    },\n    {\n      \"@type\": \"Review\",\n      \"reviewRating\": {\n        \"@type\": \"Rating\",\n        \"ratingValue\": \"4\",\n        \"bestRating\": \"5\"\n      },\n      \"author\": {\n        \"@type\": \"Person\",\n        \"name\": \"Li Si\"\n      },\n      \"reviewBody\": \"Great sound quality and comfortable fit.\",\n      \"itemReviewed\": {\n        \"@type\": \"Product\",\n        \"name\": \"High-Performance Wireless Headphones\"\n      }\n    }\n  ]\n}\n",[51,5906,5907,5911,5921,5932,5939,5943,5953,5964,5976,5986,5990,5994,6005,6012,6023,6035,6045,6050,6057,6068,6078,6082,6094,6102,6113,6123,6128,6133,6138],{"__ignoreMap":49},[519,5908,5909],{"class":521,"line":522},[519,5910,2599],{"class":529},[519,5912,5913,5915,5917,5919],{"class":521,"line":533},[519,5914,5501],{"class":536},[519,5916,540],{"class":529},[519,5918,5506],{"class":1379},[519,5920,2620],{"class":529},[519,5922,5923,5925,5927,5930],{"class":521,"line":553},[519,5924,5513],{"class":536},[519,5926,540],{"class":529},[519,5928,5929],{"class":1379},"\"WebPage\"",[519,5931,2620],{"class":529},[519,5933,5934,5937],{"class":521,"line":566},[519,5935,5936],{"class":536},"  \"@graph\"",[519,5938,3222],{"class":529},[519,5940,5941],{"class":521,"line":578},[519,5942,5640],{"class":529},[519,5944,5945,5947,5949,5951],{"class":521,"line":591},[519,5946,5645],{"class":536},[519,5948,540],{"class":529},[519,5950,5518],{"class":1379},[519,5952,2620],{"class":529},[519,5954,5955,5957,5959,5962],{"class":521,"line":1408},[519,5956,5657],{"class":536},[519,5958,540],{"class":529},[519,5960,5961],{"class":1379},"\"High-Performance Wireless Headphones\"",[519,5963,2620],{"class":529},[519,5965,5966,5969,5971,5974],{"class":521,"line":1414},[519,5967,5968],{"class":536},"      \"price\"",[519,5970,540],{"class":529},[519,5972,5973],{"class":1379},"\"299.00\"",[519,5975,2620],{"class":529},[519,5977,5978,5981,5983],{"class":521,"line":1425},[519,5979,5980],{"class":536},"      \"currency\"",[519,5982,540],{"class":529},[519,5984,5985],{"class":1379},"\"CNY\"\n",[519,5987,5988],{"class":521,"line":1435},[519,5989,5703],{"class":529},[519,5991,5992],{"class":521,"line":1446},[519,5993,5640],{"class":529},[519,5995,5996,5998,6000,6003],{"class":521,"line":1457},[519,5997,5645],{"class":536},[519,5999,540],{"class":529},[519,6001,6002],{"class":1379},"\"Review\"",[519,6004,2620],{"class":529},[519,6006,6007,6010],{"class":521,"line":1584},[519,6008,6009],{"class":536},"      \"reviewRating\"",[519,6011,2607],{"class":529},[519,6013,6014,6016,6018,6021],{"class":521,"line":1589},[519,6015,5676],{"class":536},[519,6017,540],{"class":529},[519,6019,6020],{"class":1379},"\"Rating\"",[519,6022,2620],{"class":529},[519,6024,6025,6028,6030,6033],{"class":521,"line":5720},[519,6026,6027],{"class":536},"        \"ratingValue\"",[519,6029,540],{"class":529},[519,6031,6032],{"class":1379},"\"4\"",[519,6034,2620],{"class":529},[519,6036,6037,6040,6042],{"class":521,"line":5732},[519,6038,6039],{"class":536},"        \"bestRating\"",[519,6041,540],{"class":529},[519,6043,6044],{"class":1379},"\"5\"\n",[519,6046,6047],{"class":521,"line":5739},[519,6048,6049],{"class":529},"      },\n",[519,6051,6052,6055],{"class":521,"line":5750},[519,6053,6054],{"class":536},"      \"author\"",[519,6056,2607],{"class":529},[519,6058,6059,6061,6063,6066],{"class":521,"line":5760},[519,6060,5676],{"class":536},[519,6062,540],{"class":529},[519,6064,6065],{"class":1379},"\"Person\"",[519,6067,2620],{"class":529},[519,6069,6070,6073,6075],{"class":521,"line":5765},[519,6071,6072],{"class":536},"        \"name\"",[519,6074,540],{"class":529},[519,6076,6077],{"class":1379},"\"Li Si\"\n",[519,6079,6080],{"class":521,"line":5770},[519,6081,6049],{"class":529},[519,6083,6084,6087,6089,6092],{"class":521,"line":5776},[519,6085,6086],{"class":536},"      \"reviewBody\"",[519,6088,540],{"class":529},[519,6090,6091],{"class":1379},"\"Great sound quality and comfortable fit.\"",[519,6093,2620],{"class":529},[519,6095,6097,6100],{"class":521,"line":6096},23,[519,6098,6099],{"class":536},"      \"itemReviewed\"",[519,6101,2607],{"class":529},[519,6103,6105,6107,6109,6111],{"class":521,"line":6104},24,[519,6106,5676],{"class":536},[519,6108,540],{"class":529},[519,6110,5518],{"class":1379},[519,6112,2620],{"class":529},[519,6114,6116,6118,6120],{"class":521,"line":6115},25,[519,6117,6072],{"class":536},[519,6119,540],{"class":529},[519,6121,6122],{"class":1379},"\"High-Performance Wireless Headphones\"\n",[519,6124,6126],{"class":521,"line":6125},26,[519,6127,5698],{"class":529},[519,6129,6131],{"class":521,"line":6130},27,[519,6132,3782],{"class":529},[519,6134,6136],{"class":521,"line":6135},28,[519,6137,5773],{"class":529},[519,6139,6141],{"class":521,"line":6140},29,[519,6142,594],{"class":529},[35,6144,6146],{"id":6145},"best-practices-for-json-ld","Best Practices for JSON-LD",[15,6148,6149,6155,6161,6167],{},[18,6150,6151,6154],{},[21,6152,6153],{},"Ensure relevance:"," Data must match visible page content.",[18,6156,6157,6160],{},[21,6158,6159],{},"Avoid duplication:"," Keep consistent structured data.",[18,6162,6163,6166],{},[21,6164,6165],{},"Follow search engine guidelines:"," Use formats compliant with Google and others.",[18,6168,6169,6172],{},[21,6170,6171],{},"Validate regularly:"," Use tools like Google Rich Results Test and JSON-LD Playground.",[35,6174,6176],{"id":6175},"faqs","FAQs",[11,6178,6179,6182,6183,6186,6187,390],{},[21,6180,6181],{},"Can I add multiple JSON-LD blocks per page?","\nYes, either via multiple ",[51,6184,6185],{},"\u003Cscript>"," tags or combined with ",[51,6188,5474],{},[11,6190,6191,6194],{},[21,6192,6193],{},"Where should JSON-LD be placed?","\nAnywhere on pages with relevant content — homepage, products, blogs.",[11,6196,6197,6200],{},[21,6198,6199],{},"How to validate JSON-LD?","\nUse:",[15,6202,6203,6210],{},[18,6204,6205],{},[371,6206,6209],{"href":6207,"rel":6208},"https://search.google.com/test/rich-results",[388],"Google Rich Results Test",[18,6211,6212],{},[371,6213,6216],{"href":6214,"rel":6215},"https://json-ld.org/playground/",[388],"JSON-LD Playground",[11,6218,6219,6222],{},[21,6220,6221],{},"Difference between FAQPage and QAPage?","\nFAQPage is static Q&A; QAPage supports dynamic user-generated Q&A.",[35,6224,6226],{"id":6225},"practical-json-ld-examples","Practical JSON-LD Examples",[11,6228,6229],{},[21,6230,6231],{},"Blog Post",[43,6233,6235],{"className":2439,"code":6234,"language":2441,"meta":49,"style":49},"{\n  \"@context\": \"https://schema.org\",\n  \"@type\": \"BlogPosting\",\n  \"headline\": \"SEO Optimization Strategies for 2025\",\n  \"author\": {\"@type\": \"Person\", \"name\": \"Zhang San\"},\n  \"datePublished\": \"2025-03-01T10:00:00+08:00\",\n  \"publisher\": {\n    \"@type\": \"Organization\",\n    \"name\": \"YouZhan SEO\",\n    \"logo\": {\"@type\": \"ImageObject\", \"url\": \"https://example.com/logo.png\"}\n  },\n  \"image\": \"https://example.com/blog-image.jpg\",\n  \"description\": \"Best practices to boost your SEO in 2025.\"\n}\n",[51,6236,6237,6241,6251,6262,6274,6302,6314,6321,6332,6344,6370,6374,6386,6395],{"__ignoreMap":49},[519,6238,6239],{"class":521,"line":522},[519,6240,2599],{"class":529},[519,6242,6243,6245,6247,6249],{"class":521,"line":533},[519,6244,5501],{"class":536},[519,6246,540],{"class":529},[519,6248,5506],{"class":1379},[519,6250,2620],{"class":529},[519,6252,6253,6255,6257,6260],{"class":521,"line":553},[519,6254,5513],{"class":536},[519,6256,540],{"class":529},[519,6258,6259],{"class":1379},"\"BlogPosting\"",[519,6261,2620],{"class":529},[519,6263,6264,6267,6269,6272],{"class":521,"line":566},[519,6265,6266],{"class":536},"  \"headline\"",[519,6268,540],{"class":529},[519,6270,6271],{"class":1379},"\"SEO Optimization Strategies for 2025\"",[519,6273,2620],{"class":529},[519,6275,6276,6279,6282,6285,6287,6289,6291,6294,6296,6299],{"class":521,"line":578},[519,6277,6278],{"class":536},"  \"author\"",[519,6280,6281],{"class":529},": {",[519,6283,6284],{"class":536},"\"@type\"",[519,6286,540],{"class":529},[519,6288,6065],{"class":1379},[519,6290,774],{"class":529},[519,6292,6293],{"class":536},"\"name\"",[519,6295,540],{"class":529},[519,6297,6298],{"class":1379},"\"Zhang San\"",[519,6300,6301],{"class":529},"},\n",[519,6303,6304,6307,6309,6312],{"class":521,"line":591},[519,6305,6306],{"class":536},"  \"datePublished\"",[519,6308,540],{"class":529},[519,6310,6311],{"class":1379},"\"2025-03-01T10:00:00+08:00\"",[519,6313,2620],{"class":529},[519,6315,6316,6319],{"class":521,"line":1408},[519,6317,6318],{"class":536},"  \"publisher\"",[519,6320,2607],{"class":529},[519,6322,6323,6325,6327,6330],{"class":521,"line":1414},[519,6324,5544],{"class":536},[519,6326,540],{"class":529},[519,6328,6329],{"class":1379},"\"Organization\"",[519,6331,2620],{"class":529},[519,6333,6334,6337,6339,6342],{"class":521,"line":1425},[519,6335,6336],{"class":536},"    \"name\"",[519,6338,540],{"class":529},[519,6340,6341],{"class":1379},"\"YouZhan SEO\"",[519,6343,2620],{"class":529},[519,6345,6346,6349,6351,6353,6355,6358,6360,6363,6365,6368],{"class":521,"line":1435},[519,6347,6348],{"class":536},"    \"logo\"",[519,6350,6281],{"class":529},[519,6352,6284],{"class":536},[519,6354,540],{"class":529},[519,6356,6357],{"class":1379},"\"ImageObject\"",[519,6359,774],{"class":529},[519,6361,6362],{"class":536},"\"url\"",[519,6364,540],{"class":529},[519,6366,6367],{"class":1379},"\"https://example.com/logo.png\"",[519,6369,594],{"class":529},[519,6371,6372],{"class":521,"line":1446},[519,6373,5847],{"class":529},[519,6375,6376,6379,6381,6384],{"class":521,"line":1457},[519,6377,6378],{"class":536},"  \"image\"",[519,6380,540],{"class":529},[519,6382,6383],{"class":1379},"\"https://example.com/blog-image.jpg\"",[519,6385,2620],{"class":529},[519,6387,6388,6390,6392],{"class":521,"line":1584},[519,6389,5852],{"class":536},[519,6391,540],{"class":529},[519,6393,6394],{"class":1379},"\"Best practices to boost your SEO in 2025.\"\n",[519,6396,6397],{"class":521,"line":1589},[519,6398,594],{"class":529},[11,6400,6401],{},[21,6402,5327],{},[43,6404,6406],{"className":2439,"code":6405,"language":2441,"meta":49,"style":49},"{\n  \"@context\": \"https://schema.org\",\n  \"@type\": \"Product\",\n  \"name\": \"Wireless Headphones\",\n  \"brand\": {\"@type\": \"Brand\", \"name\": \"SoundMaster\"},\n  \"offers\": {\n    \"@type\": \"Offer\",\n    \"priceCurrency\": \"CNY\",\n    \"price\": \"299.00\",\n    \"availability\": \"https://schema.org/InStock\"\n  }\n}\n",[51,6407,6408,6412,6422,6432,6443,6468,6474,6484,6495,6505,6513,6517],{"__ignoreMap":49},[519,6409,6410],{"class":521,"line":522},[519,6411,2599],{"class":529},[519,6413,6414,6416,6418,6420],{"class":521,"line":533},[519,6415,5501],{"class":536},[519,6417,540],{"class":529},[519,6419,5506],{"class":1379},[519,6421,2620],{"class":529},[519,6423,6424,6426,6428,6430],{"class":521,"line":553},[519,6425,5513],{"class":536},[519,6427,540],{"class":529},[519,6429,5518],{"class":1379},[519,6431,2620],{"class":529},[519,6433,6434,6436,6438,6441],{"class":521,"line":566},[519,6435,5525],{"class":536},[519,6437,540],{"class":529},[519,6439,6440],{"class":1379},"\"Wireless Headphones\"",[519,6442,2620],{"class":529},[519,6444,6445,6448,6450,6452,6454,6457,6459,6461,6463,6466],{"class":521,"line":578},[519,6446,6447],{"class":536},"  \"brand\"",[519,6449,6281],{"class":529},[519,6451,6284],{"class":536},[519,6453,540],{"class":529},[519,6455,6456],{"class":1379},"\"Brand\"",[519,6458,774],{"class":529},[519,6460,6293],{"class":536},[519,6462,540],{"class":529},[519,6464,6465],{"class":1379},"\"SoundMaster\"",[519,6467,6301],{"class":529},[519,6469,6470,6472],{"class":521,"line":591},[519,6471,5537],{"class":536},[519,6473,2607],{"class":529},[519,6475,6476,6478,6480,6482],{"class":521,"line":1408},[519,6477,5544],{"class":536},[519,6479,540],{"class":529},[519,6481,5549],{"class":1379},[519,6483,2620],{"class":529},[519,6485,6486,6488,6490,6493],{"class":521,"line":1414},[519,6487,5568],{"class":536},[519,6489,540],{"class":529},[519,6491,6492],{"class":1379},"\"CNY\"",[519,6494,2620],{"class":529},[519,6496,6497,6499,6501,6503],{"class":521,"line":1425},[519,6498,5556],{"class":536},[519,6500,540],{"class":529},[519,6502,5973],{"class":1379},[519,6504,2620],{"class":529},[519,6506,6507,6509,6511],{"class":521,"line":1435},[519,6508,5580],{"class":536},[519,6510,540],{"class":529},[519,6512,5585],{"class":1379},[519,6514,6515],{"class":521,"line":1446},[519,6516,2726],{"class":529},[519,6518,6519],{"class":521,"line":1457},[519,6520,594],{"class":529},[11,6522,6523],{},[21,6524,5303],{},[43,6526,6528],{"className":2439,"code":6527,"language":2441,"meta":49,"style":49},"{\n  \"@context\": \"https://schema.org\",\n  \"@type\": \"Event\",\n  \"name\": \"2025 International Coding Conference\",\n  \"startDate\": \"2025-05-15T09:00:00+08:00\",\n  \"location\": {\n    \"@type\": \"Place\",\n    \"name\": \"Shanghai International Expo Center\",\n    \"address\": {\n      \"@type\": \"PostalAddress\",\n      \"streetAddress\": \"888 Century Avenue\",\n      \"addressLocality\": \"Shanghai\",\n      \"postalCode\": \"200000\",\n      \"addressCountry\": \"CN\"\n    }\n  }\n}\n",[51,6529,6530,6534,6544,6555,6566,6578,6585,6596,6607,6614,6625,6637,6649,6661,6671,6675,6679],{"__ignoreMap":49},[519,6531,6532],{"class":521,"line":522},[519,6533,2599],{"class":529},[519,6535,6536,6538,6540,6542],{"class":521,"line":533},[519,6537,5501],{"class":536},[519,6539,540],{"class":529},[519,6541,5506],{"class":1379},[519,6543,2620],{"class":529},[519,6545,6546,6548,6550,6553],{"class":521,"line":553},[519,6547,5513],{"class":536},[519,6549,540],{"class":529},[519,6551,6552],{"class":1379},"\"Event\"",[519,6554,2620],{"class":529},[519,6556,6557,6559,6561,6564],{"class":521,"line":566},[519,6558,5525],{"class":536},[519,6560,540],{"class":529},[519,6562,6563],{"class":1379},"\"2025 International Coding Conference\"",[519,6565,2620],{"class":529},[519,6567,6568,6571,6573,6576],{"class":521,"line":578},[519,6569,6570],{"class":536},"  \"startDate\"",[519,6572,540],{"class":529},[519,6574,6575],{"class":1379},"\"2025-05-15T09:00:00+08:00\"",[519,6577,2620],{"class":529},[519,6579,6580,6583],{"class":521,"line":591},[519,6581,6582],{"class":536},"  \"location\"",[519,6584,2607],{"class":529},[519,6586,6587,6589,6591,6594],{"class":521,"line":1408},[519,6588,5544],{"class":536},[519,6590,540],{"class":529},[519,6592,6593],{"class":1379},"\"Place\"",[519,6595,2620],{"class":529},[519,6597,6598,6600,6602,6605],{"class":521,"line":1414},[519,6599,6336],{"class":536},[519,6601,540],{"class":529},[519,6603,6604],{"class":1379},"\"Shanghai International Expo Center\"",[519,6606,2620],{"class":529},[519,6608,6609,6612],{"class":521,"line":1425},[519,6610,6611],{"class":536},"    \"address\"",[519,6613,2607],{"class":529},[519,6615,6616,6618,6620,6623],{"class":521,"line":1435},[519,6617,5645],{"class":536},[519,6619,540],{"class":529},[519,6621,6622],{"class":1379},"\"PostalAddress\"",[519,6624,2620],{"class":529},[519,6626,6627,6630,6632,6635],{"class":521,"line":1446},[519,6628,6629],{"class":536},"      \"streetAddress\"",[519,6631,540],{"class":529},[519,6633,6634],{"class":1379},"\"888 Century Avenue\"",[519,6636,2620],{"class":529},[519,6638,6639,6642,6644,6647],{"class":521,"line":1457},[519,6640,6641],{"class":536},"      \"addressLocality\"",[519,6643,540],{"class":529},[519,6645,6646],{"class":1379},"\"Shanghai\"",[519,6648,2620],{"class":529},[519,6650,6651,6654,6656,6659],{"class":521,"line":1584},[519,6652,6653],{"class":536},"      \"postalCode\"",[519,6655,540],{"class":529},[519,6657,6658],{"class":1379},"\"200000\"",[519,6660,2620],{"class":529},[519,6662,6663,6666,6668],{"class":521,"line":1589},[519,6664,6665],{"class":536},"      \"addressCountry\"",[519,6667,540],{"class":529},[519,6669,6670],{"class":1379},"\"CN\"\n",[519,6672,6673],{"class":521,"line":5720},[519,6674,3782],{"class":529},[519,6676,6677],{"class":521,"line":5732},[519,6678,2726],{"class":529},[519,6680,6681],{"class":521,"line":5739},[519,6682,594],{"class":529},[35,6684,6686],{"id":6685},"references","References",[15,6688,6689,6696,6703],{},[18,6690,6691],{},[371,6692,6695],{"href":6693,"rel":6694},"https://schema.org",[388],"Schema.org Official Documentation",[18,6697,6698],{},[371,6699,6702],{"href":6700,"rel":6701},"https://developers.google.com/search/docs/appearance/structured-data/intro",[388],"Google Structured Data Guidelines",[18,6704,6705],{},[371,6706,6709],{"href":6707,"rel":6708},"https://json-ld.org",[388],"JSON-LD Official Site",[980,6711,6712],{},"html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .s9eBZ, html code.shiki .s9eBZ{--shiki-default:#22863A;--shiki-dark:#85E89D}html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}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 .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}",{"title":49,"searchDepth":533,"depth":533,"links":6714},[6715,6716,6717,6718,6719,6723,6725,6726,6727,6729,6730,6731,6732],{"id":5081,"depth":533,"text":5082},{"id":5088,"depth":533,"text":5089},{"id":5121,"depth":533,"text":5122},{"id":5213,"depth":533,"text":5214},{"id":5279,"depth":533,"text":5280,"children":6720},[6721,6722],{"id":5283,"depth":553,"text":5284},{"id":5337,"depth":553,"text":5338},{"id":5411,"depth":533,"text":6724},"Choosing Correct @type",{"id":5478,"depth":533,"text":5479},{"id":5781,"depth":533,"text":5782},{"id":5887,"depth":533,"text":6728},"The @graph Keyword",{"id":6145,"depth":533,"text":6146},{"id":6175,"depth":533,"text":6176},{"id":6225,"depth":533,"text":6226},{"id":6685,"depth":533,"text":6686},"Master JSON-LD essentials, multilingual support, SEO strategies, and best practices to enhance your website's search visibility and user experience.",{"date":6735,"category":6736,"tags":6737,"thumbnail":49,"order":522,"meta-description":6744,"meta-keyword":6745},"2025-08-03","SEO & Structured Data",[6738,6739,6740,6741,6742,6743],"JSON-LD","SEO","Structured Data","Schema.org","Multilingual","Web Development","Learn how to leverage JSON-LD for structured data, improving SEO, enabling rich search results, and supporting multiple languages with practical examples.","JSON-LD, SEO optimization, Schema.org, Structured Data, Multilingual SEO, Rich Snippets","/en/blog/json-ld",{"title":5076,"description":6733},"en/blog/json-ld","IVslZbg2hcf0fljWuzld2PG5CE3o13901kd2c7Zqoh8",{"id":6751,"title":6752,"body":6753,"description":6832,"extension":1026,"meta":6833,"navigation":1039,"path":6844,"seo":6845,"stem":6846,"__hash__":6847},"en/en/blog/lenis-overflow-scroll-on-popup-is-not-working.md","Fix: Lenis Not Working Inside Popup or Modal",{"type":8,"value":6754,"toc":6830},[6755,6769,6772,6781,6827],[11,6756,3684,6757,6760,6761,6764,6765,6768],{},[21,6758,6759],{},"Lenis"," for smooth scrolling in modern web projects, you may find that scrolling inside a ",[21,6762,6763],{},"popup"," or ",[21,6766,6767],{},"modal"," window doesn’t behave correctly. The content might feel locked or fail to scroll smoothly.",[11,6770,6771],{},"The issue happens because Lenis takes over scroll behavior globally, which interferes with nested scrollable areas like modals.",[11,6773,3701,6774,6776,6777,6780],{},[21,6775,3704],{}," Add the ",[51,6778,6779],{},"data-lenis-prevent"," attribute to the container that should be excluded from Lenis control. This allows the modal to handle its own scrolling.",[43,6782,6784],{"className":1355,"code":6783,"language":1357,"meta":49,"style":49},"\u003Cdiv class=\"popup\" data-lenis-prevent>\n  \u003Cp>This is popup content that scrolls normally.\u003C/p>\n\u003C/div>\n",[51,6785,6786,6806,6819],{"__ignoreMap":49},[519,6787,6788,6790,6793,6796,6798,6801,6804],{"class":521,"line":522},[519,6789,1364],{"class":529},[519,6791,6792],{"class":1367},"div",[519,6794,6795],{"class":525}," class",[519,6797,1376],{"class":529},[519,6799,6800],{"class":1379},"\"popup\"",[519,6802,6803],{"class":525}," data-lenis-prevent",[519,6805,1460],{"class":529},[519,6807,6808,6810,6812,6815,6817],{"class":521,"line":533},[519,6809,1488],{"class":529},[519,6811,11],{"class":1367},[519,6813,6814],{"class":529},">This is popup content that scrolls normally.\u003C/",[519,6816,11],{"class":1367},[519,6818,1460],{"class":529},[519,6820,6821,6823,6825],{"class":521,"line":553},[519,6822,1592],{"class":529},[519,6824,6792],{"class":1367},[519,6826,1460],{"class":529},[980,6828,6829],{},"html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .s9eBZ, html code.shiki .s9eBZ{--shiki-default:#22863A;--shiki-dark:#85E89D}html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}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 .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":49,"searchDepth":533,"depth":533,"links":6831},[],"Resolve Lenis smooth scroll issues inside popups or modals by using the data-lenis-prevent attribute. A practical guide with explanation and code snippet.",{"date":6834,"category":5064,"tags":6835,"order":522,"meta-description":6842,"meta-keyword":6843},"2025-09-02",[6759,6836,6837,5064,6838,6839,6840,6841],"Smooth Scroll","JavaScript","Popup","Modal","Scroll Issue","UI/UX","Discover how to fix Lenis smooth scroll not working inside a popup or modal. Learn why it happens and how to use data-lenis-prevent to avoid scroll lock problems.","Lenis, smooth scroll, Lenis popup issue, modal scroll fix, data-lenis-prevent, JavaScript UI, frontend development, Lenis not working","/en/blog/lenis-overflow-scroll-on-popup-is-not-working",{"title":6752,"description":6832},"en/blog/lenis-overflow-scroll-on-popup-is-not-working","aqGDdFrCnT-PyoNW_uYkw5zo8RghoKFkgbhWUQa3U4I",{"id":6849,"title":6850,"body":6851,"description":9065,"extension":1026,"meta":9066,"navigation":1039,"path":9077,"seo":9078,"stem":9079,"__hash__":9080},"en/en/blog/nuxt-content-dynamic-sitemap.md","How to Generate a Dynamic Sitemap from Nuxt Content",{"type":8,"value":6852,"toc":9036},[6853,6864,6870,6873,6877,6883,7053,7059,7151,7161,7165,7176,7182,7185,7191,7194,7200,7203,7207,7224,7404,7407,7495,7502,7506,7513,7769,7772,7779,7783,7790,8361,8364,8368,8371,8464,8470,8477,8483,8486,8716,8725,8729,8739,8742,8804,8807,8811,8814,8817,8831,8840,8844,8847,8895,8899,8903,8913,8917,8920,8924,8930,8934,8937,8943,8952,8954,8958,8961,8965,8968,8979,8982,8986,8995,8999,9006,9008,9033],[11,6854,6855,6856,6859,6860,6863],{},"A file-based blog can still have a dynamic URL problem. Nuxt knows that ",[51,6857,6858],{},"pages/blog/[slug].vue"," exists, but it cannot infer every real slug stored in Nuxt Content. If those article URLs are missing from ",[51,6861,6862],{},"sitemap.xml",", search engines receive an incomplete map of the site.",[11,6865,6866,6867,390],{},"The reliable solution is to query the content collection on the server, transform every document into a sitemap entry, and register that endpoint as a source for ",[51,6868,6869],{},"@nuxtjs/sitemap",[11,6871,6872],{},"This guide uses Nuxt Content v3 and the current Nuxt Sitemap module. It works for SSR projects and can also be used in a statically generated Nuxt site.",[35,6874,6876],{"id":6875},"the-short-answer","The Short Answer",[11,6878,6879,6880,434],{},"Create a sitemap source at ",[51,6881,6882],{},"server/api/__sitemap__/urls.ts",[43,6884,6888],{"className":6885,"code":6886,"language":6887,"meta":49,"style":49},"language-ts shiki shiki-themes github-light github-dark","import { queryCollection } from '#imports'\n\nexport default defineSitemapEventHandler(async (event) => {\n  const posts = await queryCollection(event, 'blog')\n    .select('path', 'date', 'updated')\n    .all()\n\n  return posts.map(post => ({\n    loc: post.path,\n    lastmod: post.updated || post.date,\n  }))\n})\n","ts",[51,6889,6890,6904,6908,6940,6966,6991,7001,7005,7027,7032,7043,7048],{"__ignoreMap":49},[519,6891,6892,6895,6898,6901],{"class":521,"line":522},[519,6893,6894],{"class":546},"import",[519,6896,6897],{"class":529}," { queryCollection } ",[519,6899,6900],{"class":546},"from",[519,6902,6903],{"class":1379}," '#imports'\n",[519,6905,6906],{"class":521,"line":533},[519,6907,1887],{"emptyLinePlaceholder":1039},[519,6909,6910,6913,6916,6919,6922,6925,6928,6932,6935,6938],{"class":521,"line":553},[519,6911,6912],{"class":546},"export",[519,6914,6915],{"class":546}," default",[519,6917,6918],{"class":525}," defineSitemapEventHandler",[519,6920,6921],{"class":529},"(",[519,6923,6924],{"class":546},"async",[519,6926,6927],{"class":529}," (",[519,6929,6931],{"class":6930},"s4XuR","event",[519,6933,6934],{"class":529},") ",[519,6936,6937],{"class":546},"=>",[519,6939,530],{"class":529},[519,6941,6942,6945,6948,6951,6954,6957,6960,6963],{"class":521,"line":566},[519,6943,6944],{"class":546},"  const",[519,6946,6947],{"class":536}," posts",[519,6949,6950],{"class":546}," =",[519,6952,6953],{"class":546}," await",[519,6955,6956],{"class":525}," queryCollection",[519,6958,6959],{"class":529},"(event, ",[519,6961,6962],{"class":1379},"'blog'",[519,6964,6965],{"class":529},")\n",[519,6967,6968,6971,6974,6976,6979,6981,6984,6986,6989],{"class":521,"line":578},[519,6969,6970],{"class":529},"    .",[519,6972,6973],{"class":525},"select",[519,6975,6921],{"class":529},[519,6977,6978],{"class":1379},"'path'",[519,6980,774],{"class":529},[519,6982,6983],{"class":1379},"'date'",[519,6985,774],{"class":529},[519,6987,6988],{"class":1379},"'updated'",[519,6990,6965],{"class":529},[519,6992,6993,6995,6998],{"class":521,"line":591},[519,6994,6970],{"class":529},[519,6996,6997],{"class":525},"all",[519,6999,7000],{"class":529},"()\n",[519,7002,7003],{"class":521,"line":1408},[519,7004,1887],{"emptyLinePlaceholder":1039},[519,7006,7007,7010,7013,7016,7018,7021,7024],{"class":521,"line":1414},[519,7008,7009],{"class":546},"  return",[519,7011,7012],{"class":529}," posts.",[519,7014,7015],{"class":525},"map",[519,7017,6921],{"class":529},[519,7019,7020],{"class":6930},"post",[519,7022,7023],{"class":546}," =>",[519,7025,7026],{"class":529}," ({\n",[519,7028,7029],{"class":521,"line":1425},[519,7030,7031],{"class":529},"    loc: post.path,\n",[519,7033,7034,7037,7040],{"class":521,"line":1435},[519,7035,7036],{"class":529},"    lastmod: post.updated ",[519,7038,7039],{"class":546},"||",[519,7041,7042],{"class":529}," post.date,\n",[519,7044,7045],{"class":521,"line":1446},[519,7046,7047],{"class":529},"  }))\n",[519,7049,7050],{"class":521,"line":1457},[519,7051,7052],{"class":529},"})\n",[11,7054,7055,7056,434],{},"Then register the source in ",[51,7057,7058],{},"nuxt.config.ts",[43,7060,7062],{"className":6885,"code":7061,"language":6887,"meta":49,"style":49},"export default defineNuxtConfig({\n  modules: [\n    '@nuxtjs/sitemap',\n    '@nuxt/content',\n  ],\n\n  site: {\n    url: 'https://example.com',\n  },\n\n  sitemap: {\n    sources: ['/api/__sitemap__/urls'],\n  },\n})\n",[51,7063,7064,7076,7081,7088,7095,7100,7104,7109,7119,7123,7127,7132,7143,7147],{"__ignoreMap":49},[519,7065,7066,7068,7070,7073],{"class":521,"line":522},[519,7067,6912],{"class":546},[519,7069,6915],{"class":546},[519,7071,7072],{"class":525}," defineNuxtConfig",[519,7074,7075],{"class":529},"({\n",[519,7077,7078],{"class":521,"line":533},[519,7079,7080],{"class":529},"  modules: [\n",[519,7082,7083,7086],{"class":521,"line":553},[519,7084,7085],{"class":1379},"    '@nuxtjs/sitemap'",[519,7087,2620],{"class":529},[519,7089,7090,7093],{"class":521,"line":566},[519,7091,7092],{"class":1379},"    '@nuxt/content'",[519,7094,2620],{"class":529},[519,7096,7097],{"class":521,"line":578},[519,7098,7099],{"class":529},"  ],\n",[519,7101,7102],{"class":521,"line":591},[519,7103,1887],{"emptyLinePlaceholder":1039},[519,7105,7106],{"class":521,"line":1408},[519,7107,7108],{"class":529},"  site: {\n",[519,7110,7111,7114,7117],{"class":521,"line":1414},[519,7112,7113],{"class":529},"    url: ",[519,7115,7116],{"class":1379},"'https://example.com'",[519,7118,2620],{"class":529},[519,7120,7121],{"class":521,"line":1425},[519,7122,5847],{"class":529},[519,7124,7125],{"class":521,"line":1435},[519,7126,1887],{"emptyLinePlaceholder":1039},[519,7128,7129],{"class":521,"line":1446},[519,7130,7131],{"class":529},"  sitemap: {\n",[519,7133,7134,7137,7140],{"class":521,"line":1457},[519,7135,7136],{"class":529},"    sources: [",[519,7138,7139],{"class":1379},"'/api/__sitemap__/urls'",[519,7141,7142],{"class":529},"],\n",[519,7144,7145],{"class":521,"line":1584},[519,7146,5847],{"class":529},[519,7148,7149],{"class":521,"line":1589},[519,7150,7052],{"class":529},[11,7152,7153,7154,7157,7158,390],{},"After starting or generating the site, open ",[51,7155,7156],{},"/sitemap.xml"," and confirm that it contains the actual article URLs rather than the placeholder route ",[51,7159,7160],{},"/blog/[slug]",[35,7162,7164],{"id":7163},"why-nuxt-dynamic-routes-need-extra-sitemap-data","Why Nuxt Dynamic Routes Need Extra Sitemap Data",[11,7166,7167,7168,7171,7172,7175],{},"Nuxt can discover static routes such as ",[51,7169,7170],{},"/about"," from the ",[51,7173,7174],{},"pages"," directory. A parameterized route is different:",[43,7177,7180],{"className":7178,"code":7179,"language":48,"meta":49},[46],"pages/\n└── blog/\n    └── [slug].vue\n",[51,7181,7179],{"__ignoreMap":49},[11,7183,7184],{},"The file describes a route pattern, not the list of valid URLs. The actual slugs may come from Markdown files, a CMS, or an API:",[43,7186,7189],{"className":7187,"code":7188,"language":48,"meta":49},[46],"content/\n└── blog/\n    ├── nuxt-seo-guide.md\n    └── fix-canonical-urls.md\n",[51,7190,7188],{"__ignoreMap":49},[11,7192,7193],{},"Nuxt Content generates paths for page collections, so these documents might become:",[43,7195,7198],{"className":7196,"code":7197,"language":48,"meta":49},[46],"/blog/nuxt-seo-guide\n/blog/fix-canonical-urls\n",[51,7199,7197],{"__ignoreMap":49},[11,7201,7202],{},"The sitemap module needs those resolved paths. A server-side collection query provides them without maintaining a second manual list.",[35,7204,7206],{"id":7205},"step-1-define-a-typed-blog-collection","Step 1: Define a Typed Blog Collection",[11,7208,7209,7210,7213,7214,774,7217,3895,7220,7223],{},"A page collection gives each document a generated ",[51,7211,7212],{},"path",". Adding a schema also makes fields such as ",[51,7215,7216],{},"date",[51,7218,7219],{},"updated",[51,7221,7222],{},"draft"," easy to query safely.",[43,7225,7227],{"className":6885,"code":7226,"language":6887,"meta":49,"style":49},"// content.config.ts\nimport { defineCollection, defineContentConfig, z } from '@nuxt/content'\n\nexport default defineContentConfig({\n  collections: {\n    blog: defineCollection({\n      type: 'page',\n      source: 'blog/**/*.md',\n      schema: z.object({\n        date: z.string(),\n        updated: z.string().optional(),\n        draft: z.boolean().default(false),\n        category: z.string().optional(),\n        tags: z.array(z.string()).default([]),\n      }),\n    }),\n  },\n})\n",[51,7228,7229,7234,7246,7250,7261,7266,7276,7286,7296,7306,7317,7332,7352,7365,7386,7391,7396,7400],{"__ignoreMap":49},[519,7230,7231],{"class":521,"line":522},[519,7232,7233],{"class":1857},"// content.config.ts\n",[519,7235,7236,7238,7241,7243],{"class":521,"line":533},[519,7237,6894],{"class":546},[519,7239,7240],{"class":529}," { defineCollection, defineContentConfig, z } ",[519,7242,6900],{"class":546},[519,7244,7245],{"class":1379}," '@nuxt/content'\n",[519,7247,7248],{"class":521,"line":553},[519,7249,1887],{"emptyLinePlaceholder":1039},[519,7251,7252,7254,7256,7259],{"class":521,"line":566},[519,7253,6912],{"class":546},[519,7255,6915],{"class":546},[519,7257,7258],{"class":525}," defineContentConfig",[519,7260,7075],{"class":529},[519,7262,7263],{"class":521,"line":578},[519,7264,7265],{"class":529},"  collections: {\n",[519,7267,7268,7271,7274],{"class":521,"line":591},[519,7269,7270],{"class":529},"    blog: ",[519,7272,7273],{"class":525},"defineCollection",[519,7275,7075],{"class":529},[519,7277,7278,7281,7284],{"class":521,"line":1408},[519,7279,7280],{"class":529},"      type: ",[519,7282,7283],{"class":1379},"'page'",[519,7285,2620],{"class":529},[519,7287,7288,7291,7294],{"class":521,"line":1414},[519,7289,7290],{"class":529},"      source: ",[519,7292,7293],{"class":1379},"'blog/**/*.md'",[519,7295,2620],{"class":529},[519,7297,7298,7301,7304],{"class":521,"line":1425},[519,7299,7300],{"class":529},"      schema: z.",[519,7302,7303],{"class":525},"object",[519,7305,7075],{"class":529},[519,7307,7308,7311,7314],{"class":521,"line":1435},[519,7309,7310],{"class":529},"        date: z.",[519,7312,7313],{"class":525},"string",[519,7315,7316],{"class":529},"(),\n",[519,7318,7319,7322,7324,7327,7330],{"class":521,"line":1446},[519,7320,7321],{"class":529},"        updated: z.",[519,7323,7313],{"class":525},[519,7325,7326],{"class":529},"().",[519,7328,7329],{"class":525},"optional",[519,7331,7316],{"class":529},[519,7333,7334,7337,7340,7342,7345,7347,7349],{"class":521,"line":1457},[519,7335,7336],{"class":529},"        draft: z.",[519,7338,7339],{"class":525},"boolean",[519,7341,7326],{"class":529},[519,7343,7344],{"class":525},"default",[519,7346,6921],{"class":529},[519,7348,2665],{"class":536},[519,7350,7351],{"class":529},"),\n",[519,7353,7354,7357,7359,7361,7363],{"class":521,"line":1584},[519,7355,7356],{"class":529},"        category: z.",[519,7358,7313],{"class":525},[519,7360,7326],{"class":529},[519,7362,7329],{"class":525},[519,7364,7316],{"class":529},[519,7366,7367,7370,7373,7376,7378,7381,7383],{"class":521,"line":1589},[519,7368,7369],{"class":529},"        tags: z.",[519,7371,7372],{"class":525},"array",[519,7374,7375],{"class":529},"(z.",[519,7377,7313],{"class":525},[519,7379,7380],{"class":529},"()).",[519,7382,7344],{"class":525},[519,7384,7385],{"class":529},"([]),\n",[519,7387,7388],{"class":521,"line":5720},[519,7389,7390],{"class":529},"      }),\n",[519,7392,7393],{"class":521,"line":5732},[519,7394,7395],{"class":529},"    }),\n",[519,7397,7398],{"class":521,"line":5739},[519,7399,5847],{"class":529},[519,7401,7402],{"class":521,"line":5750},[519,7403,7052],{"class":529},[11,7405,7406],{},"A matching Markdown file can use this frontmatter:",[43,7408,7410],{"className":2818,"code":7409,"language":2820,"meta":49,"style":49},"---\ntitle: \"How to Fix a Nuxt SEO Problem\"\ndescription: \"A concise summary for readers and search results.\"\ndate: \"2026-07-18\"\nupdated: \"2026-07-18\"\ndraft: false\ncategory: \"Nuxt\"\ntags: [\"Nuxt\", \"SEO\"]\n---\n",[51,7411,7412,7417,7427,7436,7445,7453,7462,7472,7491],{"__ignoreMap":49},[519,7413,7414],{"class":521,"line":522},[519,7415,7416],{"class":525},"---\n",[519,7418,7419,7422,7424],{"class":521,"line":533},[519,7420,7421],{"class":1367},"title",[519,7423,540],{"class":529},[519,7425,7426],{"class":1379},"\"How to Fix a Nuxt SEO Problem\"\n",[519,7428,7429,7431,7433],{"class":521,"line":553},[519,7430,5206],{"class":1367},[519,7432,540],{"class":529},[519,7434,7435],{"class":1379},"\"A concise summary for readers and search results.\"\n",[519,7437,7438,7440,7442],{"class":521,"line":566},[519,7439,7216],{"class":1367},[519,7441,540],{"class":529},[519,7443,7444],{"class":1379},"\"2026-07-18\"\n",[519,7446,7447,7449,7451],{"class":521,"line":578},[519,7448,7219],{"class":1367},[519,7450,540],{"class":529},[519,7452,7444],{"class":1379},[519,7454,7455,7457,7459],{"class":521,"line":591},[519,7456,7222],{"class":1367},[519,7458,540],{"class":529},[519,7460,7461],{"class":536},"false\n",[519,7463,7464,7467,7469],{"class":521,"line":1408},[519,7465,7466],{"class":1367},"category",[519,7468,540],{"class":529},[519,7470,7471],{"class":1379},"\"Nuxt\"\n",[519,7473,7474,7477,7480,7483,7485,7488],{"class":521,"line":1414},[519,7475,7476],{"class":1367},"tags",[519,7478,7479],{"class":529},": [",[519,7481,7482],{"class":1379},"\"Nuxt\"",[519,7484,774],{"class":529},[519,7486,7487],{"class":1379},"\"SEO\"",[519,7489,7490],{"class":529},"]\n",[519,7492,7493],{"class":521,"line":1425},[519,7494,7416],{"class":525},[11,7496,7497,7498,7501],{},"Use an ISO 8601 date such as ",[51,7499,7500],{},"YYYY-MM-DD",". More precise timestamps are also valid when the time is meaningful.",[35,7503,7505],{"id":7504},"step-2-create-the-dynamic-sitemap-endpoint","Step 2: Create the Dynamic Sitemap Endpoint",[11,7507,7508,7509,7512],{},"The server version of ",[51,7510,7511],{},"queryCollection"," receives the request event as its first argument. Filter drafts, select only the fields required by the sitemap, and return the module's expected URL objects.",[43,7514,7516],{"className":6885,"code":7515,"language":6887,"meta":49,"style":49},"// server/api/__sitemap__/urls.ts\nimport { queryCollection } from '#imports'\n\nconst normalizePath = (path: string) => {\n  if (path === '/') return '/'\n  return `${path.replace(/\\/+$/, '')}/`\n}\n\nexport default defineSitemapEventHandler(async (event) => {\n  const posts = await queryCollection(event, 'blog')\n    .where('draft', '=', false)\n    .select('path', 'date', 'updated')\n    .all()\n\n  return posts.map(post => ({\n    loc: normalizePath(post.path),\n    lastmod: post.updated || post.date,\n  }))\n})\n",[51,7517,7518,7523,7533,7537,7562,7584,7623,7627,7631,7653,7671,7694,7714,7722,7726,7742,7753,7761,7765],{"__ignoreMap":49},[519,7519,7520],{"class":521,"line":522},[519,7521,7522],{"class":1857},"// server/api/__sitemap__/urls.ts\n",[519,7524,7525,7527,7529,7531],{"class":521,"line":533},[519,7526,6894],{"class":546},[519,7528,6897],{"class":529},[519,7530,6900],{"class":546},[519,7532,6903],{"class":1379},[519,7534,7535],{"class":521,"line":553},[519,7536,1887],{"emptyLinePlaceholder":1039},[519,7538,7539,7542,7545,7547,7549,7551,7553,7556,7558,7560],{"class":521,"line":566},[519,7540,7541],{"class":546},"const",[519,7543,7544],{"class":525}," normalizePath",[519,7546,6950],{"class":546},[519,7548,6927],{"class":529},[519,7550,7212],{"class":6930},[519,7552,434],{"class":546},[519,7554,7555],{"class":536}," string",[519,7557,6934],{"class":529},[519,7559,6937],{"class":546},[519,7561,530],{"class":529},[519,7563,7564,7567,7570,7573,7576,7578,7581],{"class":521,"line":578},[519,7565,7566],{"class":546},"  if",[519,7568,7569],{"class":529}," (path ",[519,7571,7572],{"class":546},"===",[519,7574,7575],{"class":1379}," '/'",[519,7577,6934],{"class":529},[519,7579,7580],{"class":546},"return",[519,7582,7583],{"class":1379}," '/'\n",[519,7585,7586,7588,7591,7593,7595,7598,7600,7603,7607,7610,7612,7614,7617,7620],{"class":521,"line":591},[519,7587,7009],{"class":546},[519,7589,7590],{"class":1379}," `${",[519,7592,7212],{"class":529},[519,7594,390],{"class":1379},[519,7596,7597],{"class":525},"replace",[519,7599,6921],{"class":1379},[519,7601,7602],{"class":1379},"/",[519,7604,7606],{"class":7605},"snhLl","\\/",[519,7608,7609],{"class":546},"+$",[519,7611,7602],{"class":1379},[519,7613,774],{"class":1379},[519,7615,7616],{"class":1379},"''",[519,7618,7619],{"class":1379},")",[519,7621,7622],{"class":1379},"}/`\n",[519,7624,7625],{"class":521,"line":1408},[519,7626,594],{"class":529},[519,7628,7629],{"class":521,"line":1414},[519,7630,1887],{"emptyLinePlaceholder":1039},[519,7632,7633,7635,7637,7639,7641,7643,7645,7647,7649,7651],{"class":521,"line":1425},[519,7634,6912],{"class":546},[519,7636,6915],{"class":546},[519,7638,6918],{"class":525},[519,7640,6921],{"class":529},[519,7642,6924],{"class":546},[519,7644,6927],{"class":529},[519,7646,6931],{"class":6930},[519,7648,6934],{"class":529},[519,7650,6937],{"class":546},[519,7652,530],{"class":529},[519,7654,7655,7657,7659,7661,7663,7665,7667,7669],{"class":521,"line":1435},[519,7656,6944],{"class":546},[519,7658,6947],{"class":536},[519,7660,6950],{"class":546},[519,7662,6953],{"class":546},[519,7664,6956],{"class":525},[519,7666,6959],{"class":529},[519,7668,6962],{"class":1379},[519,7670,6965],{"class":529},[519,7672,7673,7675,7678,7680,7683,7685,7688,7690,7692],{"class":521,"line":1446},[519,7674,6970],{"class":529},[519,7676,7677],{"class":525},"where",[519,7679,6921],{"class":529},[519,7681,7682],{"class":1379},"'draft'",[519,7684,774],{"class":529},[519,7686,7687],{"class":1379},"'='",[519,7689,774],{"class":529},[519,7691,2665],{"class":536},[519,7693,6965],{"class":529},[519,7695,7696,7698,7700,7702,7704,7706,7708,7710,7712],{"class":521,"line":1457},[519,7697,6970],{"class":529},[519,7699,6973],{"class":525},[519,7701,6921],{"class":529},[519,7703,6978],{"class":1379},[519,7705,774],{"class":529},[519,7707,6983],{"class":1379},[519,7709,774],{"class":529},[519,7711,6988],{"class":1379},[519,7713,6965],{"class":529},[519,7715,7716,7718,7720],{"class":521,"line":1584},[519,7717,6970],{"class":529},[519,7719,6997],{"class":525},[519,7721,7000],{"class":529},[519,7723,7724],{"class":521,"line":1589},[519,7725,1887],{"emptyLinePlaceholder":1039},[519,7727,7728,7730,7732,7734,7736,7738,7740],{"class":521,"line":5720},[519,7729,7009],{"class":546},[519,7731,7012],{"class":529},[519,7733,7015],{"class":525},[519,7735,6921],{"class":529},[519,7737,7020],{"class":6930},[519,7739,7023],{"class":546},[519,7741,7026],{"class":529},[519,7743,7744,7747,7750],{"class":521,"line":5732},[519,7745,7746],{"class":529},"    loc: ",[519,7748,7749],{"class":525},"normalizePath",[519,7751,7752],{"class":529},"(post.path),\n",[519,7754,7755,7757,7759],{"class":521,"line":5739},[519,7756,7036],{"class":529},[519,7758,7039],{"class":546},[519,7760,7042],{"class":529},[519,7762,7763],{"class":521,"line":5750},[519,7764,7047],{"class":529},[519,7766,7767],{"class":521,"line":5760},[519,7768,7052],{"class":529},[11,7770,7771],{},"The normalization function is optional. Use it when the public site has a trailing-slash convention and make sure canonical URLs follow the same convention.",[11,7773,7774,7775,7778],{},"Do not set ",[51,7776,7777],{},"lastmod"," to the current time on every build. That tells crawlers every page changed even when the article did not. Use the real publication or modification date instead.",[35,7780,7782],{"id":7781},"step-3-add-static-and-taxonomy-urls","Step 3: Add Static and Taxonomy URLs",[11,7784,7785,7786,7789],{},"The endpoint can combine content URLs with routes for categories, tags, and important static pages. A ",[51,7787,7788],{},"Set"," prevents duplicate taxonomy entries.",[43,7791,7793],{"className":6885,"code":7792,"language":6887,"meta":49,"style":49},"// server/api/__sitemap__/urls.ts\nimport { queryCollection } from '#imports'\n\nconst slugify = (value: string) => value\n  .trim()\n  .toLowerCase()\n  .replace(/&/g, 'and')\n  .replace(/[^a-z0-9]+/g, '-')\n  .replace(/(^-|-$)/g, '')\n\nexport default defineSitemapEventHandler(async (event) => {\n  const posts = await queryCollection(event, 'blog')\n    .where('draft', '=', false)\n    .select('path', 'date', 'updated', 'category', 'tags')\n    .all()\n\n  const categories = new Set\u003Cstring>()\n  const tags = new Set\u003Cstring>()\n\n  const articleUrls = posts.map((post) => {\n    if (post.category) categories.add(post.category)\n    post.tags.forEach(tag => tags.add(tag))\n\n    return {\n      loc: post.path,\n      lastmod: post.updated || post.date,\n    }\n  })\n\n  return [\n    { loc: '/' },\n    { loc: '/blog/' },\n    { loc: '/about/' },\n    ...articleUrls,\n    ...Array.from(categories).map(category => ({\n      loc: `/categories/${slugify(category)}/`,\n    })),\n    ...Array.from(tags).map(tag => ({\n      loc: `/tags/${slugify(tag)}/`,\n    })),\n  ]\n})\n",[51,7794,7795,7799,7809,7813,7838,7848,7857,7883,7916,7953,7957,7979,7997,8017,8047,8055,8059,8081,8100,8104,8128,8142,8165,8169,8176,8181,8190,8194,8199,8203,8211,8223,8233,8243,8252,8275,8298,8304,8326,8346,8351,8356],{"__ignoreMap":49},[519,7796,7797],{"class":521,"line":522},[519,7798,7522],{"class":1857},[519,7800,7801,7803,7805,7807],{"class":521,"line":533},[519,7802,6894],{"class":546},[519,7804,6897],{"class":529},[519,7806,6900],{"class":546},[519,7808,6903],{"class":1379},[519,7810,7811],{"class":521,"line":553},[519,7812,1887],{"emptyLinePlaceholder":1039},[519,7814,7815,7817,7820,7822,7824,7827,7829,7831,7833,7835],{"class":521,"line":566},[519,7816,7541],{"class":546},[519,7818,7819],{"class":525}," slugify",[519,7821,6950],{"class":546},[519,7823,6927],{"class":529},[519,7825,7826],{"class":6930},"value",[519,7828,434],{"class":546},[519,7830,7555],{"class":536},[519,7832,6934],{"class":529},[519,7834,6937],{"class":546},[519,7836,7837],{"class":529}," value\n",[519,7839,7840,7843,7846],{"class":521,"line":578},[519,7841,7842],{"class":529},"  .",[519,7844,7845],{"class":525},"trim",[519,7847,7000],{"class":529},[519,7849,7850,7852,7855],{"class":521,"line":591},[519,7851,7842],{"class":529},[519,7853,7854],{"class":525},"toLowerCase",[519,7856,7000],{"class":529},[519,7858,7859,7861,7863,7865,7867,7871,7873,7876,7878,7881],{"class":521,"line":1408},[519,7860,7842],{"class":529},[519,7862,7597],{"class":525},[519,7864,6921],{"class":529},[519,7866,7602],{"class":1379},[519,7868,7870],{"class":7869},"sA_wV","&",[519,7872,7602],{"class":1379},[519,7874,7875],{"class":546},"g",[519,7877,774],{"class":529},[519,7879,7880],{"class":1379},"'and'",[519,7882,6965],{"class":529},[519,7884,7885,7887,7889,7891,7893,7896,7899,7902,7905,7907,7909,7911,7914],{"class":521,"line":1414},[519,7886,7842],{"class":529},[519,7888,7597],{"class":525},[519,7890,6921],{"class":529},[519,7892,7602],{"class":1379},[519,7894,7895],{"class":536},"[",[519,7897,7898],{"class":546},"^",[519,7900,7901],{"class":536},"a-z0-9]",[519,7903,7904],{"class":546},"+",[519,7906,7602],{"class":1379},[519,7908,7875],{"class":546},[519,7910,774],{"class":529},[519,7912,7913],{"class":1379},"'-'",[519,7915,6965],{"class":529},[519,7917,7918,7920,7922,7924,7926,7928,7930,7933,7936,7938,7941,7943,7945,7947,7949,7951],{"class":521,"line":1425},[519,7919,7842],{"class":529},[519,7921,7597],{"class":525},[519,7923,6921],{"class":529},[519,7925,7602],{"class":1379},[519,7927,6921],{"class":7869},[519,7929,7898],{"class":546},[519,7931,7932],{"class":7869},"-",[519,7934,7935],{"class":546},"|",[519,7937,7932],{"class":7869},[519,7939,7940],{"class":546},"$",[519,7942,7619],{"class":7869},[519,7944,7602],{"class":1379},[519,7946,7875],{"class":546},[519,7948,774],{"class":529},[519,7950,7616],{"class":1379},[519,7952,6965],{"class":529},[519,7954,7955],{"class":521,"line":1435},[519,7956,1887],{"emptyLinePlaceholder":1039},[519,7958,7959,7961,7963,7965,7967,7969,7971,7973,7975,7977],{"class":521,"line":1446},[519,7960,6912],{"class":546},[519,7962,6915],{"class":546},[519,7964,6918],{"class":525},[519,7966,6921],{"class":529},[519,7968,6924],{"class":546},[519,7970,6927],{"class":529},[519,7972,6931],{"class":6930},[519,7974,6934],{"class":529},[519,7976,6937],{"class":546},[519,7978,530],{"class":529},[519,7980,7981,7983,7985,7987,7989,7991,7993,7995],{"class":521,"line":1457},[519,7982,6944],{"class":546},[519,7984,6947],{"class":536},[519,7986,6950],{"class":546},[519,7988,6953],{"class":546},[519,7990,6956],{"class":525},[519,7992,6959],{"class":529},[519,7994,6962],{"class":1379},[519,7996,6965],{"class":529},[519,7998,7999,8001,8003,8005,8007,8009,8011,8013,8015],{"class":521,"line":1584},[519,8000,6970],{"class":529},[519,8002,7677],{"class":525},[519,8004,6921],{"class":529},[519,8006,7682],{"class":1379},[519,8008,774],{"class":529},[519,8010,7687],{"class":1379},[519,8012,774],{"class":529},[519,8014,2665],{"class":536},[519,8016,6965],{"class":529},[519,8018,8019,8021,8023,8025,8027,8029,8031,8033,8035,8037,8040,8042,8045],{"class":521,"line":1589},[519,8020,6970],{"class":529},[519,8022,6973],{"class":525},[519,8024,6921],{"class":529},[519,8026,6978],{"class":1379},[519,8028,774],{"class":529},[519,8030,6983],{"class":1379},[519,8032,774],{"class":529},[519,8034,6988],{"class":1379},[519,8036,774],{"class":529},[519,8038,8039],{"class":1379},"'category'",[519,8041,774],{"class":529},[519,8043,8044],{"class":1379},"'tags'",[519,8046,6965],{"class":529},[519,8048,8049,8051,8053],{"class":521,"line":5720},[519,8050,6970],{"class":529},[519,8052,6997],{"class":525},[519,8054,7000],{"class":529},[519,8056,8057],{"class":521,"line":5732},[519,8058,1887],{"emptyLinePlaceholder":1039},[519,8060,8061,8063,8066,8068,8071,8074,8076,8078],{"class":521,"line":5739},[519,8062,6944],{"class":546},[519,8064,8065],{"class":536}," categories",[519,8067,6950],{"class":546},[519,8069,8070],{"class":546}," new",[519,8072,8073],{"class":525}," Set",[519,8075,1364],{"class":529},[519,8077,7313],{"class":536},[519,8079,8080],{"class":529},">()\n",[519,8082,8083,8085,8088,8090,8092,8094,8096,8098],{"class":521,"line":5750},[519,8084,6944],{"class":546},[519,8086,8087],{"class":536}," tags",[519,8089,6950],{"class":546},[519,8091,8070],{"class":546},[519,8093,8073],{"class":525},[519,8095,1364],{"class":529},[519,8097,7313],{"class":536},[519,8099,8080],{"class":529},[519,8101,8102],{"class":521,"line":5760},[519,8103,1887],{"emptyLinePlaceholder":1039},[519,8105,8106,8108,8111,8113,8115,8117,8120,8122,8124,8126],{"class":521,"line":5765},[519,8107,6944],{"class":546},[519,8109,8110],{"class":536}," articleUrls",[519,8112,6950],{"class":546},[519,8114,7012],{"class":529},[519,8116,7015],{"class":525},[519,8118,8119],{"class":529},"((",[519,8121,7020],{"class":6930},[519,8123,6934],{"class":529},[519,8125,6937],{"class":546},[519,8127,530],{"class":529},[519,8129,8130,8133,8136,8139],{"class":521,"line":5770},[519,8131,8132],{"class":546},"    if",[519,8134,8135],{"class":529}," (post.category) categories.",[519,8137,8138],{"class":525},"add",[519,8140,8141],{"class":529},"(post.category)\n",[519,8143,8144,8147,8150,8152,8155,8157,8160,8162],{"class":521,"line":5776},[519,8145,8146],{"class":529},"    post.tags.",[519,8148,8149],{"class":525},"forEach",[519,8151,6921],{"class":529},[519,8153,8154],{"class":6930},"tag",[519,8156,7023],{"class":546},[519,8158,8159],{"class":529}," tags.",[519,8161,8138],{"class":525},[519,8163,8164],{"class":529},"(tag))\n",[519,8166,8167],{"class":521,"line":6096},[519,8168,1887],{"emptyLinePlaceholder":1039},[519,8170,8171,8174],{"class":521,"line":6104},[519,8172,8173],{"class":546},"    return",[519,8175,530],{"class":529},[519,8177,8178],{"class":521,"line":6115},[519,8179,8180],{"class":529},"      loc: post.path,\n",[519,8182,8183,8186,8188],{"class":521,"line":6125},[519,8184,8185],{"class":529},"      lastmod: post.updated ",[519,8187,7039],{"class":546},[519,8189,7042],{"class":529},[519,8191,8192],{"class":521,"line":6130},[519,8193,3782],{"class":529},[519,8195,8196],{"class":521,"line":6135},[519,8197,8198],{"class":529},"  })\n",[519,8200,8201],{"class":521,"line":6140},[519,8202,1887],{"emptyLinePlaceholder":1039},[519,8204,8206,8208],{"class":521,"line":8205},30,[519,8207,7009],{"class":546},[519,8209,8210],{"class":529}," [\n",[519,8212,8214,8217,8220],{"class":521,"line":8213},31,[519,8215,8216],{"class":529},"    { loc: ",[519,8218,8219],{"class":1379},"'/'",[519,8221,8222],{"class":529}," },\n",[519,8224,8226,8228,8231],{"class":521,"line":8225},32,[519,8227,8216],{"class":529},[519,8229,8230],{"class":1379},"'/blog/'",[519,8232,8222],{"class":529},[519,8234,8236,8238,8241],{"class":521,"line":8235},33,[519,8237,8216],{"class":529},[519,8239,8240],{"class":1379},"'/about/'",[519,8242,8222],{"class":529},[519,8244,8246,8249],{"class":521,"line":8245},34,[519,8247,8248],{"class":546},"    ...",[519,8250,8251],{"class":529},"articleUrls,\n",[519,8253,8255,8257,8260,8262,8265,8267,8269,8271,8273],{"class":521,"line":8254},35,[519,8256,8248],{"class":546},[519,8258,8259],{"class":529},"Array.",[519,8261,6900],{"class":525},[519,8263,8264],{"class":529},"(categories).",[519,8266,7015],{"class":525},[519,8268,6921],{"class":529},[519,8270,7466],{"class":6930},[519,8272,7023],{"class":546},[519,8274,7026],{"class":529},[519,8276,8278,8281,8284,8287,8289,8291,8293,8296],{"class":521,"line":8277},36,[519,8279,8280],{"class":529},"      loc: ",[519,8282,8283],{"class":1379},"`/categories/${",[519,8285,8286],{"class":525},"slugify",[519,8288,6921],{"class":1379},[519,8290,7466],{"class":529},[519,8292,7619],{"class":1379},[519,8294,8295],{"class":1379},"}/`",[519,8297,2620],{"class":529},[519,8299,8301],{"class":521,"line":8300},37,[519,8302,8303],{"class":529},"    })),\n",[519,8305,8307,8309,8311,8313,8316,8318,8320,8322,8324],{"class":521,"line":8306},38,[519,8308,8248],{"class":546},[519,8310,8259],{"class":529},[519,8312,6900],{"class":525},[519,8314,8315],{"class":529},"(tags).",[519,8317,7015],{"class":525},[519,8319,6921],{"class":529},[519,8321,8154],{"class":6930},[519,8323,7023],{"class":546},[519,8325,7026],{"class":529},[519,8327,8329,8331,8334,8336,8338,8340,8342,8344],{"class":521,"line":8328},39,[519,8330,8280],{"class":529},[519,8332,8333],{"class":1379},"`/tags/${",[519,8335,8286],{"class":525},[519,8337,6921],{"class":1379},[519,8339,8154],{"class":529},[519,8341,7619],{"class":1379},[519,8343,8295],{"class":1379},[519,8345,2620],{"class":529},[519,8347,8349],{"class":521,"line":8348},40,[519,8350,8303],{"class":529},[519,8352,8354],{"class":521,"line":8353},41,[519,8355,5773],{"class":529},[519,8357,8359],{"class":521,"line":8358},42,[519,8360,7052],{"class":529},[11,8362,8363],{},"Only include indexable URLs that return a successful response. Login pages, internal search results, preview routes, draft content, and redirects generally do not belong in the sitemap.",[35,8365,8367],{"id":8366},"step-4-register-the-source","Step 4: Register the Source",[11,8369,8370],{},"Add the endpoint to the sitemap configuration:",[43,8372,8374],{"className":6885,"code":8373,"language":6887,"meta":49,"style":49},"// nuxt.config.ts\nexport default defineNuxtConfig({\n  modules: [\n    '@nuxtjs/sitemap',\n    '@nuxt/content',\n  ],\n\n  site: {\n    url: 'https://example.com',\n    trailingSlash: true,\n  },\n\n  sitemap: {\n    sources: ['/api/__sitemap__/urls'],\n  },\n})\n",[51,8375,8376,8381,8391,8395,8401,8407,8411,8415,8419,8427,8436,8440,8444,8448,8456,8460],{"__ignoreMap":49},[519,8377,8378],{"class":521,"line":522},[519,8379,8380],{"class":1857},"// nuxt.config.ts\n",[519,8382,8383,8385,8387,8389],{"class":521,"line":533},[519,8384,6912],{"class":546},[519,8386,6915],{"class":546},[519,8388,7072],{"class":525},[519,8390,7075],{"class":529},[519,8392,8393],{"class":521,"line":553},[519,8394,7080],{"class":529},[519,8396,8397,8399],{"class":521,"line":566},[519,8398,7085],{"class":1379},[519,8400,2620],{"class":529},[519,8402,8403,8405],{"class":521,"line":578},[519,8404,7092],{"class":1379},[519,8406,2620],{"class":529},[519,8408,8409],{"class":521,"line":591},[519,8410,7099],{"class":529},[519,8412,8413],{"class":521,"line":1408},[519,8414,1887],{"emptyLinePlaceholder":1039},[519,8416,8417],{"class":521,"line":1414},[519,8418,7108],{"class":529},[519,8420,8421,8423,8425],{"class":521,"line":1425},[519,8422,7113],{"class":529},[519,8424,7116],{"class":1379},[519,8426,2620],{"class":529},[519,8428,8429,8432,8434],{"class":521,"line":1435},[519,8430,8431],{"class":529},"    trailingSlash: ",[519,8433,2617],{"class":536},[519,8435,2620],{"class":529},[519,8437,8438],{"class":521,"line":1446},[519,8439,5847],{"class":529},[519,8441,8442],{"class":521,"line":1457},[519,8443,1887],{"emptyLinePlaceholder":1039},[519,8445,8446],{"class":521,"line":1584},[519,8447,7131],{"class":529},[519,8449,8450,8452,8454],{"class":521,"line":1589},[519,8451,7136],{"class":529},[519,8453,7139],{"class":1379},[519,8455,7142],{"class":529},[519,8457,8458],{"class":521,"line":5720},[519,8459,5847],{"class":529},[519,8461,8462],{"class":521,"line":5732},[519,8463,7052],{"class":529},[11,8465,5888,8466,8469],{},[51,8467,8468],{},"site.url"," value is important because it lets the module turn relative paths into absolute URLs for the deployed domain.",[35,8471,8473,8474],{"id":8472},"handling-frontmatter-stored-under-meta","Handling Frontmatter Stored Under ",[51,8475,8476],{},"meta",[11,8478,8479,8480,8482],{},"If a collection does not define a custom schema, extra frontmatter fields may be available under the document's ",[51,8481,8476],{}," object instead of as top-level properties.",[11,8484,8485],{},"Use this variation:",[43,8487,8489],{"className":6885,"code":8488,"language":6887,"meta":49,"style":49},"import { queryCollection } from '#imports'\n\ntype PostMeta = {\n  date?: string\n  updated?: string\n  draft?: boolean\n}\n\nexport default defineSitemapEventHandler(async (event) => {\n  const posts = await queryCollection(event, 'blog')\n    .select('path', 'meta')\n    .all()\n\n  return posts.flatMap((post) => {\n    const meta = post.meta as PostMeta\n\n    if (meta.draft) return []\n\n    return [{\n      loc: post.path,\n      lastmod: meta.updated || meta.date,\n    }]\n  })\n})\n",[51,8490,8491,8501,8505,8517,8528,8537,8547,8551,8555,8577,8595,8612,8620,8624,8643,8662,8666,8678,8682,8689,8693,8703,8708,8712],{"__ignoreMap":49},[519,8492,8493,8495,8497,8499],{"class":521,"line":522},[519,8494,6894],{"class":546},[519,8496,6897],{"class":529},[519,8498,6900],{"class":546},[519,8500,6903],{"class":1379},[519,8502,8503],{"class":521,"line":533},[519,8504,1887],{"emptyLinePlaceholder":1039},[519,8506,8507,8510,8513,8515],{"class":521,"line":553},[519,8508,8509],{"class":546},"type",[519,8511,8512],{"class":525}," PostMeta",[519,8514,6950],{"class":546},[519,8516,530],{"class":529},[519,8518,8519,8522,8525],{"class":521,"line":566},[519,8520,8521],{"class":6930},"  date",[519,8523,8524],{"class":546},"?:",[519,8526,8527],{"class":536}," string\n",[519,8529,8530,8533,8535],{"class":521,"line":578},[519,8531,8532],{"class":6930},"  updated",[519,8534,8524],{"class":546},[519,8536,8527],{"class":536},[519,8538,8539,8542,8544],{"class":521,"line":591},[519,8540,8541],{"class":6930},"  draft",[519,8543,8524],{"class":546},[519,8545,8546],{"class":536}," boolean\n",[519,8548,8549],{"class":521,"line":1408},[519,8550,594],{"class":529},[519,8552,8553],{"class":521,"line":1414},[519,8554,1887],{"emptyLinePlaceholder":1039},[519,8556,8557,8559,8561,8563,8565,8567,8569,8571,8573,8575],{"class":521,"line":1425},[519,8558,6912],{"class":546},[519,8560,6915],{"class":546},[519,8562,6918],{"class":525},[519,8564,6921],{"class":529},[519,8566,6924],{"class":546},[519,8568,6927],{"class":529},[519,8570,6931],{"class":6930},[519,8572,6934],{"class":529},[519,8574,6937],{"class":546},[519,8576,530],{"class":529},[519,8578,8579,8581,8583,8585,8587,8589,8591,8593],{"class":521,"line":1435},[519,8580,6944],{"class":546},[519,8582,6947],{"class":536},[519,8584,6950],{"class":546},[519,8586,6953],{"class":546},[519,8588,6956],{"class":525},[519,8590,6959],{"class":529},[519,8592,6962],{"class":1379},[519,8594,6965],{"class":529},[519,8596,8597,8599,8601,8603,8605,8607,8610],{"class":521,"line":1446},[519,8598,6970],{"class":529},[519,8600,6973],{"class":525},[519,8602,6921],{"class":529},[519,8604,6978],{"class":1379},[519,8606,774],{"class":529},[519,8608,8609],{"class":1379},"'meta'",[519,8611,6965],{"class":529},[519,8613,8614,8616,8618],{"class":521,"line":1457},[519,8615,6970],{"class":529},[519,8617,6997],{"class":525},[519,8619,7000],{"class":529},[519,8621,8622],{"class":521,"line":1584},[519,8623,1887],{"emptyLinePlaceholder":1039},[519,8625,8626,8628,8630,8633,8635,8637,8639,8641],{"class":521,"line":1589},[519,8627,7009],{"class":546},[519,8629,7012],{"class":529},[519,8631,8632],{"class":525},"flatMap",[519,8634,8119],{"class":529},[519,8636,7020],{"class":6930},[519,8638,6934],{"class":529},[519,8640,6937],{"class":546},[519,8642,530],{"class":529},[519,8644,8645,8648,8651,8653,8656,8659],{"class":521,"line":5720},[519,8646,8647],{"class":546},"    const",[519,8649,8650],{"class":536}," meta",[519,8652,6950],{"class":546},[519,8654,8655],{"class":529}," post.meta ",[519,8657,8658],{"class":546},"as",[519,8660,8661],{"class":525}," PostMeta\n",[519,8663,8664],{"class":521,"line":5732},[519,8665,1887],{"emptyLinePlaceholder":1039},[519,8667,8668,8670,8673,8675],{"class":521,"line":5739},[519,8669,8132],{"class":546},[519,8671,8672],{"class":529}," (meta.draft) ",[519,8674,7580],{"class":546},[519,8676,8677],{"class":529}," []\n",[519,8679,8680],{"class":521,"line":5750},[519,8681,1887],{"emptyLinePlaceholder":1039},[519,8683,8684,8686],{"class":521,"line":5760},[519,8685,8173],{"class":546},[519,8687,8688],{"class":529}," [{\n",[519,8690,8691],{"class":521,"line":5765},[519,8692,8180],{"class":529},[519,8694,8695,8698,8700],{"class":521,"line":5770},[519,8696,8697],{"class":529},"      lastmod: meta.updated ",[519,8699,7039],{"class":546},[519,8701,8702],{"class":529}," meta.date,\n",[519,8704,8705],{"class":521,"line":5776},[519,8706,8707],{"class":529},"    }]\n",[519,8709,8710],{"class":521,"line":6096},[519,8711,8198],{"class":529},[519,8713,8714],{"class":521,"line":6104},[519,8715,7052],{"class":529},[11,8717,8718,8719,8721,8722,390],{},"Inspect one query result if you are unsure where a field is stored. A common cause of an empty or undated sitemap is selecting ",[51,8720,7216],{}," when the actual value is ",[51,8723,8724],{},"meta.date",[35,8726,8728],{"id":8727},"fixing-locale-prefixes","Fixing Locale Prefixes",[11,8730,8731,8732,8735,8736,390],{},"Content paths and public URLs are not always identical in multilingual projects. For example, a file may produce ",[51,8733,8734],{},"/en/blog/example",", while the default locale is publicly served at ",[51,8737,8738],{},"/blog/example",[11,8740,8741],{},"Transform the path before returning it:",[43,8743,8745],{"className":6885,"code":8744,"language":6887,"meta":49,"style":49},"const toPublicPath = (path: string) => {\n  return path.replace(/^\\/en\\//, '/')\n}\n",[51,8746,8747,8770,8800],{"__ignoreMap":49},[519,8748,8749,8751,8754,8756,8758,8760,8762,8764,8766,8768],{"class":521,"line":522},[519,8750,7541],{"class":546},[519,8752,8753],{"class":525}," toPublicPath",[519,8755,6950],{"class":546},[519,8757,6927],{"class":529},[519,8759,7212],{"class":6930},[519,8761,434],{"class":546},[519,8763,7555],{"class":536},[519,8765,6934],{"class":529},[519,8767,6937],{"class":546},[519,8769,530],{"class":529},[519,8771,8772,8774,8777,8779,8781,8783,8785,8787,8790,8792,8794,8796,8798],{"class":521,"line":533},[519,8773,7009],{"class":546},[519,8775,8776],{"class":529}," path.",[519,8778,7597],{"class":525},[519,8780,6921],{"class":529},[519,8782,7602],{"class":1379},[519,8784,7898],{"class":546},[519,8786,7606],{"class":7605},[519,8788,8789],{"class":7869},"en",[519,8791,7606],{"class":7605},[519,8793,7602],{"class":1379},[519,8795,774],{"class":529},[519,8797,8219],{"class":1379},[519,8799,6965],{"class":529},[519,8801,8802],{"class":521,"line":553},[519,8803,594],{"class":529},[11,8805,8806],{},"For non-default locales, return the correct localized path and add alternate language URLs when appropriate. Never publish an internal content path that redirects to a different public URL.",[35,8808,8810],{"id":8809},"sitemap-discovery-is-not-the-same-as-prerendering","Sitemap Discovery Is Not the Same as Prerendering",[11,8812,8813],{},"A sitemap helps crawlers discover URLs. It does not automatically guarantee that every dynamic page is emitted as HTML during static generation.",[11,8815,8816],{},"For an SSG deployment, make sure at least one of these is true:",[15,8818,8819,8822,8828],{},[18,8820,8821],{},"The blog index links to every article and Nitro's prerender crawler can follow those links.",[18,8823,8824,8825,390],{},"Dynamic routes are added to ",[51,8826,8827],{},"nitro.prerender.routes",[18,8829,8830],{},"Your build setup uses a content-aware integration that adds the routes.",[11,8832,8833,8834,8837,8838,390],{},"After running ",[51,8835,8836],{},"nuxt generate",", inspect the generated output for both the article HTML files and ",[51,8839,6862],{},[35,8841,8843],{"id":8842},"validation-checklist","Validation Checklist",[11,8845,8846],{},"Before deploying, check the following:",[60,8848,8849,8855,8860,8867,8883,8886,8892],{},[18,8850,383,8851,8854],{},[51,8852,8853],{},"/api/__sitemap__/urls"," and verify that it returns a JSON array.",[18,8856,383,8857,8859],{},[51,8858,7156],{}," and search for a recent article slug.",[18,8861,8862,8863,8866],{},"Confirm that every ",[51,8864,8865],{},"\u003Cloc>"," uses the production domain and preferred slash format.",[18,8868,8869,8870,8873,8874,774,8877,778,8880,390],{},"Test several sitemap URLs and make sure they return ",[51,8871,8872],{},"200",", not ",[51,8875,8876],{},"301",[51,8878,8879],{},"404",[51,8881,8882],{},"500",[18,8884,8885],{},"Confirm that drafts and private pages are absent.",[18,8887,8888,8889,8891],{},"Verify that ",[51,8890,7777],{}," changes only when the corresponding content changes.",[18,8893,8894],{},"Submit the production sitemap URL in Google Search Console.",[35,8896,8898],{"id":8897},"common-problems","Common Problems",[153,8900,8902],{"id":8901},"the-sitemap-contains-no-blog-posts","The Sitemap Contains No Blog Posts",[11,8904,8905,8906,8909,8910,390],{},"Check the collection name, source glob, and query fields. ",[51,8907,8908],{},"queryCollection(event, 'blog')"," must use the exact key defined in ",[51,8911,8912],{},"content.config.ts",[153,8914,8916],{"id":8915},"paths-include-an-unwanted-locale","Paths Include an Unwanted Locale",[11,8918,8919],{},"Map internal content paths to their public route equivalents before returning them from the endpoint.",[153,8921,8923],{"id":8922},"the-endpoint-works-in-development-but-not-after-static-generation","The Endpoint Works in Development but Not After Static Generation",[11,8925,8926,8927,8929],{},"Confirm that the sitemap is generated during the build and that the output contains ",[51,8928,6862],{},". A runtime-only server endpoint cannot execute later on a purely static host.",[153,8931,8933],{"id":8932},"canonical-urls-and-sitemap-urls-disagree","Canonical URLs and Sitemap URLs Disagree",[11,8935,8936],{},"Choose one URL format and apply it everywhere. Redirects, canonical tags, internal links, and sitemap entries should point to the same preferred URL. A sitemap is a canonicalization signal, but it should not be used to compensate for conflicting tags.",[153,8938,8940,8941],{"id":8939},"every-build-changes-lastmod","Every Build Changes ",[51,8942,7777],{},[11,8944,3252,8945,8948,8949,8951],{},[51,8946,8947],{},"new Date()"," as the default for unchanged content. Store an actual ",[51,8950,7219],{}," value in frontmatter or fall back to the publication date.",[35,8953,896],{"id":895},[153,8955,8957],{"id":8956},"does-nuxt-automatically-add-nuxt-content-pages-to-the-sitemap","Does Nuxt automatically add Nuxt Content pages to the sitemap?",[11,8959,8960],{},"Static pages can be discovered automatically, but dynamic slug routes may require a content integration or a custom URL source. Always inspect the generated XML instead of assuming every document is included.",[153,8962,8964],{"id":8963},"should-a-sitemap-include-categories-and-tags","Should a sitemap include categories and tags?",[11,8966,8967],{},"Include them when those pages are useful, indexable landing pages with unique content. Exclude empty, duplicate, or thin taxonomy pages.",[153,8969,8971,8972,788,8975,8978],{"id":8970},"do-priority-and-changefreq-improve-rankings","Do ",[51,8973,8974],{},"priority",[51,8976,8977],{},"changefreq"," improve rankings?",[11,8980,8981],{},"They do not replace crawlable architecture, accurate canonical URLs, or useful content. Focus first on complete URL coverage and truthful modification dates.",[153,8983,8985],{"id":8984},"can-i-use-the-same-approach-with-an-external-cms","Can I use the same approach with an external CMS?",[11,8987,8988,8989,8992,8993,390],{},"Yes. Replace the collection query with an API request and map the CMS records to objects containing at least ",[51,8990,8991],{},"loc",", with an optional ",[51,8994,7777],{},[35,8996,8998],{"id":8997},"next-steps","Next Steps",[11,9000,9001,9002,390],{},"A complete sitemap is one part of technical SEO. Each article should also have a unique title, description, canonical URL, crawlable internal links, and relevant structured data. For the structured-data layer, see the ",[371,9003,9005],{"href":9004},"/blog/json-ld/","JSON-LD guide for SEO",[11,9007,2080],{},[15,9009,9010,9017,9026],{},[18,9011,9012],{},[371,9013,9016],{"href":9014,"rel":9015},"https://nuxtseo.com/docs/sitemap/guides/dynamic-urls",[388],"Nuxt Sitemap dynamic URL endpoints",[18,9018,9019],{},[371,9020,9023,9024],{"href":9021,"rel":9022},"https://content.nuxt.com/docs/utils/query-collection",[388],"Nuxt Content ",[51,9025,7511],{},[18,9027,9028],{},[371,9029,9032],{"href":9030,"rel":9031},"https://developers.google.com/search/docs/crawling-indexing/sitemaps/overview",[388],"Google Search sitemap documentation",[980,9034,9035],{},"html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .s4XuR, html code.shiki .s4XuR{--shiki-default:#E36209;--shiki-dark:#FFAB70}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}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 .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sJ8bj, html code.shiki .sJ8bj{--shiki-default:#6A737D;--shiki-dark:#6A737D}html pre.shiki code .s9eBZ, html code.shiki .s9eBZ{--shiki-default:#22863A;--shiki-dark:#85E89D}html pre.shiki code .snhLl, html code.shiki .snhLl{--shiki-default:#22863A;--shiki-default-font-weight:bold;--shiki-dark:#85E89D;--shiki-dark-font-weight:bold}html pre.shiki code .sA_wV, html code.shiki .sA_wV{--shiki-default:#032F62;--shiki-dark:#DBEDFF}",{"title":49,"searchDepth":533,"depth":533,"links":9037},[9038,9039,9040,9041,9042,9043,9044,9046,9047,9048,9049,9057,9064],{"id":6875,"depth":533,"text":6876},{"id":7163,"depth":533,"text":7164},{"id":7205,"depth":533,"text":7206},{"id":7504,"depth":533,"text":7505},{"id":7781,"depth":533,"text":7782},{"id":8366,"depth":533,"text":8367},{"id":8472,"depth":533,"text":9045},"Handling Frontmatter Stored Under meta",{"id":8727,"depth":533,"text":8728},{"id":8809,"depth":533,"text":8810},{"id":8842,"depth":533,"text":8843},{"id":8897,"depth":533,"text":8898,"children":9050},[9051,9052,9053,9054,9055],{"id":8901,"depth":553,"text":8902},{"id":8915,"depth":553,"text":8916},{"id":8922,"depth":553,"text":8923},{"id":8932,"depth":553,"text":8933},{"id":8939,"depth":553,"text":9056},"Every Build Changes lastmod",{"id":895,"depth":533,"text":896,"children":9058},[9059,9060,9061,9063],{"id":8956,"depth":553,"text":8957},{"id":8963,"depth":553,"text":8964},{"id":8970,"depth":553,"text":9062},"Do priority and changefreq improve rankings?",{"id":8984,"depth":553,"text":8985},{"id":8997,"depth":533,"text":8998},"Build a Nuxt Content sitemap that includes every blog post, accurate last-modified dates, static pages, categories, and tags.",{"date":1028,"updated":1028,"category":9067,"tags":9068,"order":522,"meta-description":9075,"meta-keyword":9076},"Nuxt",[9067,9069,9070,9071,9072,9073,9074],"Nuxt Content","Sitemap","Technical SEO","SSG","Nitro","TypeScript","Learn how to generate a dynamic XML sitemap from Nuxt Content with @nuxtjs/sitemap, queryCollection, lastmod dates, and SSG-safe URLs.","Nuxt Content sitemap, Nuxt dynamic sitemap, @nuxtjs/sitemap, queryCollection sitemap, Nuxt SSG sitemap, technical SEO","/en/blog/nuxt-content-dynamic-sitemap",{"title":6850,"description":9065},"en/blog/nuxt-content-dynamic-sitemap","R01M-Ok_MnpCFlVbCZ9PYTmT0wuXTzF4XJvHHoeVQDQ",1784316306316]