[{"data":1,"prerenderedAt":217},["ShallowReactive",2],{"quirekit-doc:\u002Fen\u002Fbuild\u002Ffiles":3},{"id":4,"title":5,"body":6,"description":205,"extension":206,"keywords":207,"locale":208,"meta":209,"navigation":210,"order":211,"path":212,"section":213,"seo":214,"stem":215,"__hash__":216},"docs\u002Fbuild\u002Ffiles.en.md","Save and open documents",{"type":7,"value":8,"toc":197},"minimark",[9,13,18,56,67,77,81,84,91,95,98,115,125,132,136,139,145,149,163,177,180,193],[10,11,12],"p",{},"Editor modifies content; your application decides where to store it. Start with JSON backups, then validate opened files and distinguish DOCX from your native backup format.",[14,15,17],"h2",{"id":16},"_1-read-content-when-saving","1. Read content when saving",[19,20,26],"pre",{"className":21,"code":22,"filename":23,"language":24,"meta":25,"style":25},"language-ts shiki shiki-themes github-light github-light github-dark","const content = editor.getJSON()\n","Read JSON at save time","ts","",[27,28,29],"code",{"__ignoreMap":25},[30,31,34,38,42,45,49,53],"span",{"class":32,"line":33},"line",1,[30,35,37],{"class":36},"sDD9d","const",[30,39,41],{"class":40},"sUNQB"," content",[30,43,44],{"class":36}," =",[30,46,48],{"class":47},"sVPnS"," editor.",[30,50,52],{"class":51},"sgQzM","getJSON",[30,54,55],{"class":47},"()\n",[10,57,58,59,62,63,66],{},"Store the result in your database, API or browser storage. Include a version and model name, such as ",[27,60,61],{},"version: 1"," and ",[27,64,65],{},"model: 'generic-v1'",", so future versions can recognize older files.",[10,68,69,72,73,76],{},[27,70,71],{},"files\u002Frepository.ts"," uses ",[27,74,75],{},"localStorage"," for local drafts. Cross-device synchronization needs your own server.",[14,78,80],{"id":79},"_2-confirm-which-revision-was-saved","2. Confirm which revision was saved",[10,82,83],{},"Users may keep typing while saving. Capture the starting document and clear the unsaved indicator only if the current content still matches that revision.",[10,85,86,87,90],{},"Keep content and unsaved state after failure, and show an error with retry. Browser storage can fail too. ",[27,88,89],{},"session.ts"," coordinates these states without creating a second editable document in Vue.",[14,92,94],{"id":93},"_3-validate-before-restoring","3. Validate before restoring",[10,96,97],{},"Check backup version and model, then validate nodes, marks, attributes and children against Schema. Only then replace the document:",[19,99,102],{"className":21,"code":100,"filename":101,"language":24,"meta":25,"style":25},"editor.commands.replaceDocument(content)\n","Restore a validated document",[27,103,104],{"__ignoreMap":25},[30,105,106,109,112],{"class":32,"line":33},[30,107,108],{"class":47},"editor.commands.",[30,110,111],{"class":51},"replaceDocument",[30,113,114],{"class":47},"(content)\n",[10,116,117,120,121,124],{},[27,118,119],{},"replaceDocument()"," restores the complete document, including top-level attributes; ",[27,122,123],{},"setContent()"," is for ordinary content replacement. On rejection, preserve the original file and draft rather than dropping unknown nodes and overwriting the backup.",[10,126,127,128,131],{},"See ",[27,129,130],{},"files\u002Fbackup.ts"," for validation. The example requires saving edits before opening another file.",[14,133,135],{"id":134},"_4-reject-outdated-loads","4. Reject outdated loads",[10,137,138],{},"By the time asynchronous reading or conversion finishes, users may have edited, opened another file, switched to read-only or left the page.",[10,140,141,142,144],{},"Before committing, confirm the instance, operation and document still match the starting state. ",[27,143,89],{}," centralizes this check for all file actions.",[14,146,148],{"id":147},"_5-add-docx","5. Add DOCX",[10,150,151,152,155,156,159,160,162],{},"JSON preserves your product model. DOCX requires separate conversion rules. The Word workspace loads public ",[27,153,154],{},"@quirekit\u002Fclassic-docx\u002Fdocx"," APIs on demand; ",[27,157,158],{},"files\u002Fdocx.ts"," handles bytes and conversion results, while ",[27,161,89],{}," decides whether to commit them.",[10,164,165,166,169,170,62,173,176],{},"A custom workspace can reuse those conversion APIs. Classic can install ",[27,167,168],{},"createClassicWordDocxPlugin()"," and use ",[27,171,172],{},"instance.importDocument()",[27,174,175],{},"exportDocument()",".",[10,178,179],{},"Keep and display conversion diagnostics. Images also require media storage: saving a JSON reference does not save the image bytes.",[10,181,182,183,188,189,176],{},"Inspect files by purpose in the ",[184,185,187],"a",{"href":186},"\u002Fen\u002Fbuild\u002Freference","reference",". Next: ",[184,190,192],{"href":191},"\u002Fen\u002Fbuild\u002Fresources","images, fonts and product capabilities",[194,195,196],"style",{},"html pre.shiki code .sDD9d, html code.shiki .sDD9d{--shiki-default:#D73A49;--shiki-light:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sUNQB, html code.shiki .sUNQB{--shiki-default:#005CC5;--shiki-light:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sVPnS, html code.shiki .sVPnS{--shiki-default:#24292E;--shiki-light:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sgQzM, html code.shiki .sgQzM{--shiki-default:#6F42C1;--shiki-light:#6F42C1;--shiki-dark:#B392F0}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 .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-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":25,"searchDepth":198,"depth":198,"links":199},2,[200,201,202,203,204],{"id":16,"depth":198,"text":17},{"id":79,"depth":198,"text":80},{"id":93,"depth":198,"text":94},{"id":134,"depth":198,"text":135},{"id":147,"depth":198,"text":148},"Start with JSON, then add validation, asynchronous state and DOCX conversion.","md",null,"en",{},true,7,"\u002Fen\u002Fbuild\u002Ffiles","Build a product",{"title":5,"description":205},"build\u002Ffiles.en","bt89mDzxZqFA3_q99JQiG9ilNSngJcif176rgyXgjjk",1793045210308]