# Restore previous image state

To store and restore (or save and load) the editor state of a previous image editing session we can use the `history` propery.

The current `imageState` is returned in the `'process'` event and in the `'update'` event, it can also be requested by accessing the `imageState` property.

* [ ![](/pintura/static/assets/technologies-mono/javascript.svg)JavaScript](#javascript-panel-0)
* [ ![](/pintura/static/assets/technologies-mono/react.svg)React](#react-panel-0)
* [ ![](/pintura/static/assets/technologies-mono/vue.svg)Vue](#vue-panel-0)
* [ ![](/pintura/static/assets/technologies-mono/svelte.svg)Svelte](#svelte-panel-0)
* [ ![](/pintura/static/assets/technologies-mono/angular.svg)Angular](#angular-panel-0)
* [ ![](/pintura/static/assets/technologies-mono/jquery.svg)jQuery](#jquery-panel-0)

* [index.html](#index-html-panel-0)

```html
<!DOCTYPE html>

<head>
    <link rel="stylesheet" href="./pintura.css" />
</head>

<style>
    .pintura-editor {
        height: 600px;
    }
</style>

<div id="editor"></div>

<script type="module">
    import { appendDefaultEditor } from './pintura.js';

    const stringifyImageState = (imageState) => {
        return JSON.stringify(imageState, (k, v) =>
            v === undefined ? null : v
        );
    };

    const parseImageState = (str) => {
        return JSON.parse(str);
    };

    let storedImageState =
        '{"cropLimitToImage": true, "cropAspectRatio": null }';

    const editor = appendDefaultEditor('#editor', { src: 'image.jpeg' });

    editor.on('load', () => {
        // Add image state to history stack
        editor.history.write(parseImageState(storedImageState));
    });

    editor.on('process', (res) => {
        // 1. Turn imageState into string, replaces undefined values with null
        const imageStateStr = stringifyImageState(res.imageState);

        // 2. Store imageStateStr on your server for later usage
    });
</script>

```

* [App.jsx](#App-jsx-panel-0)
* [App.css](#App-css-panel-0)

```jsx
import '@pqina/pintura/pintura.css';
import './App.css';
import { useRef, useState } from 'react';
import { PinturaEditor } from '@pqina/react-pintura';
import { getEditorDefaults } from '@pqina/pintura';

const editorDefaults = getEditorDefaults();

const stringifyImageState = (imageState) => {
    return JSON.stringify(imageState, (k, v) => (v === undefined ? null : v));
};

const parseImageState = (str) => {
    return JSON.parse(str);
};

function App() {
    const [storedImageState, setStoredImageState] = useState(
        '{"cropLimitToImage": true, "cropAspectRatio": null }'
    );

    const editorRef = useRef(null);

    const handleEditorLoad = () => {
        // Add image state to history stack
        editorRef.current.editor.history.write(
            parseImageState(storedImageState)
        );
    };

    const handleEditorProcess = (res) => {
        // 1. Turn imageState into string, replaces undefined values with null
        const imageStateStr = stringifyImageState(res.imageState);

        // 2. Store imageStateStr on your server for later usage
    };

    return (
        <div className="App">
            <PinturaEditor
                ref={editorRef}
                {...editorDefaults}
                src={'image.jpeg'}
                onLoad={handleEditorLoad}
                onProcess={handleEditorProcess}
            />
        </div>
    );
}

export default App;

```

```css
.pintura-editor {
    height: 600px;
}

```

* [App.vue](#App-vue-panel-0)

```html
<template>
    <div>
        <PinturaEditor
            ref="editor"
            v-bind="editorDefaults"
            src="image.jpeg"
            v-on:pintura:load="handleEditorLoad($event)"
            v-on:pintura:process="handleEditorProcess($event)"
        />
    </div>
</template>
<script>
import { PinturaEditor } from '@pqina/vue-pintura';
import { getEditorDefaults } from '@pqina/pintura';

const stringifyImageState = function (imageState) {
    return JSON.stringify(imageState, (k, v) => (v === undefined ? null : v));
};

const parseImageState = function (str) {
    return JSON.parse(str);
};

export default {
    name: 'App',

    components: {
        PinturaEditor,
    },

    data() {
        return {
            editorDefaults: getEditorDefaults(),

            storedImageState:
                '{"cropLimitToImage": true, "cropAspectRatio": null }',
        };
    },

    methods: {
        handleEditorLoad: function () {
            // Add image state to history stack
            this.$refs.editor.editor.history.write(
                parseImageState(this.storedImageState)
            );
        },

        handleEditorProcess: function (res) {
            // 1. Turn imageState into string, replaces undefined values with null
            const imageStateStr = stringifyImageState(res.imageState);

            // 2. Store imageStateStr on your server for later usage
        },
    },
};
</script>
<style>
@import '@pqina/pintura/pintura.css';

.pintura-editor {
    height: 600px;
}
</style>

```

* [App.svelte](#App-svelte-panel-0)

```svelte
<script>
    import { PinturaEditor } from '@pqina/svelte-pintura';
    import { getEditorDefaults } from '@pqina/pintura';
    import '@pqina/pintura/pintura.css';

    const stringifyImageState = (imageState) => {
        return JSON.stringify(imageState, (k, v) =>
            v === undefined ? null : v
        );
    };

    const parseImageState = (str) => {
        return JSON.parse(str);
    };

    let editorDefaults = getEditorDefaults();

    // Previously stored image state string
    let storedImageState =
        '{"cropLimitToImage": true, "cropAspectRatio": null }';

    let editor;

    const handleEditorLoad = (event) => {
        const res = event.detail;

        // Add image state to history stack
        editor.history.write(parseImageState(storedImageState));
    };

    const handleEditorProcess = (event) => {
        const res = event.detail;

        // 1. Turn imageState into string, replaces undefined values with null
        const imageStateStr = stringifyImageState(res.imageState);

        // 2. Store imageStateStr on your server for later usage
    };
</script>

<div>
    <PinturaEditor
        bind:this={editor}
        {...editorDefaults}
        src={'image.jpeg'}
        on:load={handleEditorLoad}
        on:process={handleEditorProcess}
    />
</div>

<style>
    div :global(.pintura-editor) {
        height: 600px;
    }
</style>

```

* [app.component.ts](#app-component-ts-panel-0)
* [app.component.html](#app-component-html-panel-0)
* [app.component.css](#app-component-css-panel-0)
* [app.module.ts](#app-module-ts-panel-0)

```javascript
import { Component, ViewChild } from '@angular/core';

import { getEditorDefaults } from '@pqina/pintura';

const stringifyImageState = (imageState: PinturaImageState): string => {
    return JSON.stringify(imageState, (k, v) => (v === undefined ? null : v));
};

const parseImageState = (str: string): PinturaImageState => {
    return JSON.parse(str);
};

@Component({
    selector: 'app-root',
    templateUrl: './app.component.html',
    styleUrls: ['./app.component.css'],
})
export class AppComponent {
    @ViewChild('editor') editor?: any;

    editorDefaults: any = getEditorDefaults();

    storedImageState: string =
        '{"cropLimitToImage": true, "cropAspectRatio": null }';

    handleEditorLoad(): void {
        // Add image state to history stack
        this.editor.editor.history.write(
            parseImageState(this.storedImageState)
        );
    }

    handleEditorProcess(res: any): void {
        // 1. Turn imageState into string, replaces undefined values with null
        const imageStateStr = stringifyImageState(res.imageState);

        // 2. Store imageStateStr on your server for later usage
    }
}

```

```html
<pintura-editor
    #editor
    [options]="editorDefaults"
    src="image.jpeg"
    (load)="handleEditorLoad()"
    (process)="handleEditorProcess($event)"
></pintura-editor>

```

```css
::ng-deep .pintura-editor {
    height: 600px;
}

```

```javascript
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppComponent } from './app.component';
import { AngularPinturaModule } from '@pqina/angular-pintura';

@NgModule({
    declarations: [AppComponent],
    imports: [BrowserModule, AngularPinturaModule],
    exports: [AppComponent],
    providers: [],
    bootstrap: [AppComponent],
})
export class AppModule {}

```

* [index.html](#index-html-panel-0)

```html
<!DOCTYPE html>
<head>
    <link rel="stylesheet" href="./pintura/pintura.css" />
</head>

<script src="./jquery.js"></script>
<script src="./jquery-pintura/useEditorWithJQuery-iife.js"></script>
<script src="./pintura/pintura-iife.js"></script>

<style>
    .pintura-editor {
        height: 600px;
    }
</style>

<div id="editor"></div>

<script>
    useEditorWithJQuery(jQuery, pintura);

    $(function () {
        const stringifyImageState = (imageState) => {
            return JSON.stringify(imageState, (k, v) =>
                v === undefined ? null : v
            );
        };

        const parseImageState = (str) => {
            return JSON.parse(str);
        };

        var storedImageState =
            '{"cropLimitToImage": true, "cropAspectRatio": null }';

        var editor = $('#editor').pinturaDefault({ src: 'image.jpeg' });

        editor.on('pintura:load', function (event) {
            const res = event.detail;

            // Add image state to history stack
            editor.pintura('history').write(parseImageState(storedImageState));
        });

        editor.on('pintura:process', function (event) {
            const res = event.detail;

            // 1. Turn imageState into string, replaces undefined values with null
            const imageStateStr = stringifyImageState(res.imageState);

            // 2. Store imageStateStr on your server for later usage
        });
    });
</script>

```