Skip to content

Password Controller >=3.9.0

passwordControl

An instance object that allows programmatic password submission.

NameDescriptionType
submitPasswordSubmit a password programmatically for a password-protected PDF. Return a promise that resolves to true if the password was accepted, or false if incorrect.(password: string) => Promise<boolean>

Usage with showPasswordModal prop

By default, Vue PDF Viewer displays a built-in password modal when a password-protected PDF is loaded. To handle password input with your own custom UI, set the showPasswordModal prop to false and use passwordControl.submitPassword() to submit the password programmatically.

You can also listen to the passwordRequired, passwordError and passwordSuccess events to track the password flow.

Example

vue
<script setup lang="ts">
  import { VPdfViewer, type PasswordRequiredPayload } from '@vue-pdf-viewer/viewer';
  import { ref, computed, unref } from 'vue';

  const vpvRef = ref<InstanceType<typeof VPdfViewer>>();
  const passwordControl = computed(() => vpvRef.value?.passwordControl);
  const password = ref('');
  const showPasswordInput = ref(false);
  const errorMessage = ref('');

  const onPasswordRequired = (payload: PasswordRequiredPayload) => {
    showPasswordInput.value = true;
    if (payload.reason === 'incorrect') {
      errorMessage.value = 'Incorrect password. Please try again.';
    }
  };

  const onPasswordSuccess = () => {
    showPasswordInput.value = false;
    errorMessage.value = '';
  };

  const submitPassword = async () => {
    const ctrl = unref(passwordControl);
    if (!ctrl) return;

    const success = await ctrl.submitPassword(password.value);
    if (!success) {
      errorMessage.value = 'Incorrect password. Please try again.';
    }
  };
</script>
<template>
  <div id="vpv">
    <div v-if="showPasswordInput">
      <input
        v-model="password"
        type="password"
        placeholder="Enter password"
        @keyup.enter="submitPassword"
      />
      <button @click="submitPassword">Submit</button>
      <p v-if="errorMessage" style="color: red;">{{ errorMessage }}</p>
    </div>
    <div :style="{ width: '100%', height: '100%' }">
      <VPdfViewer
        ref="vpvRef"
        src="/path/to/password-protected.pdf"
        :showPasswordModal="false"
        @passwordRequired="onPasswordRequired"
        @passwordSuccess="onPasswordSuccess"
      />
    </div>
  </div>
</template>
<style scoped>
#vpv {
  width: 100%;
  height: 1490px;
  margin: 0 auto;
}
</style>
vue
<script setup>
  import { VPdfViewer } from '@vue-pdf-viewer/viewer';
  import { ref, computed, unref } from 'vue';

  const vpvRef = ref(null);
  const passwordControl = computed(() => vpvRef.value?.passwordControl);
  const password = ref('');
  const showPasswordInput = ref(false);
  const errorMessage = ref('');

  const onPasswordRequired = (payload) => {
    showPasswordInput.value = true;
    if (payload.reason === 'incorrect') {
      errorMessage.value = 'Incorrect password. Please try again.';
    }
  };

  const onPasswordSuccess = () => {
    showPasswordInput.value = false;
    errorMessage.value = '';
  };

  const submitPassword = async () => {
    const ctrl = unref(passwordControl);
    if (!ctrl) return;

    const success = await ctrl.submitPassword(password.value);
    if (!success) {
      errorMessage.value = 'Incorrect password. Please try again.';
    }
  };
</script>
<template>
  <div id="vpv">
    <div v-if="showPasswordInput">
      <input
        v-model="password"
        type="password"
        placeholder="Enter password"
        @keyup.enter="submitPassword"
      />
      <button @click="submitPassword">Submit</button>
      <p v-if="errorMessage" style="color: red;">{{ errorMessage }}</p>
    </div>
    <div :style="{ width: '100%', height: '100%' }">
      <VPdfViewer
        ref="vpvRef"
        src="/path/to/password-protected.pdf"
        :showPasswordModal="false"
        @passwordRequired="onPasswordRequired"
        @passwordSuccess="onPasswordSuccess"
      />
    </div>
  </div>
</template>
<style scoped>
#vpv {
  width: 100%;
  height: 1490px;
  margin: 0 auto;
}
</style>
vue
<script lang="ts">
  import { VPdfViewer, type PasswordRequiredPayload } from '@vue-pdf-viewer/viewer';
  import { computed, defineComponent, ref, unref } from 'vue';

export default defineComponent({
  components: { VPdfViewer },
  setup() {
    const vpvRef = ref<InstanceType<typeof VPdfViewer>>();
    const passwordControl = computed(() => vpvRef.value?.passwordControl);
    const password = ref('');
    const showPasswordInput = ref(false);
    const errorMessage = ref('');

    const onPasswordRequired = (payload: PasswordRequiredPayload) => {
      showPasswordInput.value = true;
      if (payload.reason === 'incorrect') {
        errorMessage.value = 'Incorrect password. Please try again.';
      }
    };

    const onPasswordSuccess = () => {
      showPasswordInput.value = false;
      errorMessage.value = '';
    };

    const submitPassword = async () => {
      const ctrl = unref(passwordControl);
      if (!ctrl) return;

      const success = await ctrl.submitPassword(password.value);
      if (!success) {
        errorMessage.value = 'Incorrect password. Please try again.';
      }
    };

    return {
      vpvRef,
      password,
      showPasswordInput,
      errorMessage,
      onPasswordRequired,
      onPasswordSuccess,
      submitPassword,
    };
  },
});
</script>
<template>
  <div id="vpv">
    <div v-if="showPasswordInput">
      <input
        v-model="password"
        type="password"
        placeholder="Enter password"
        @keyup.enter="submitPassword"
      />
      <button @click="submitPassword">Submit</button>
      <p v-if="errorMessage" style="color: red;">{{ errorMessage }}</p>
    </div>
    <div :style="{ width: '100%', height: '100%' }">
      <VPdfViewer
        ref="vpvRef"
        src="/path/to/password-protected.pdf"
        :showPasswordModal="false"
        @passwordRequired="onPasswordRequired"
        @passwordSuccess="onPasswordSuccess"
      />
    </div>
  </div>
</template>
<style scoped>
#vpv {
  width: 100%;
  height: 1490px;
  margin: 0 auto;
}
</style>
vue
<script>
  import { VPdfViewer } from '@vue-pdf-viewer/viewer';
  import { computed, ref, unref } from 'vue';

export default {
  components: { VPdfViewer },
  setup() {
    const vpvRef = ref(null);
    const passwordControl = computed(() => vpvRef.value?.passwordControl);
    const password = ref('');
    const showPasswordInput = ref(false);
    const errorMessage = ref('');

    const onPasswordRequired = (payload) => {
      showPasswordInput.value = true;
      if (payload.reason === 'incorrect') {
        errorMessage.value = 'Incorrect password. Please try again.';
      }
    };

    const onPasswordSuccess = () => {
      showPasswordInput.value = false;
      errorMessage.value = '';
    };

    const submitPassword = async () => {
      const ctrl = unref(passwordControl);
      if (!ctrl) return;

      const success = await ctrl.submitPassword(password.value);
      if (!success) {
        errorMessage.value = 'Incorrect password. Please try again.';
      }
    };

    return {
      vpvRef,
      password,
      showPasswordInput,
      errorMessage,
      onPasswordRequired,
      onPasswordSuccess,
      submitPassword,
    };
  },
};
</script>
<template>
  <div id="vpv">
    <div v-if="showPasswordInput">
      <input
        v-model="password"
        type="password"
        placeholder="Enter password"
        @keyup.enter="submitPassword"
      />
      <button @click="submitPassword">Submit</button>
      <p v-if="errorMessage" style="color: red;">{{ errorMessage }}</p>
    </div>
    <div :style="{ width: '100%', height: '100%' }">
      <VPdfViewer
        ref="vpvRef"
        src="/path/to/password-protected.pdf"
        :showPasswordModal="false"
        @passwordRequired="onPasswordRequired"
        @passwordSuccess="onPasswordSuccess"
      />
    </div>
  </div>
</template>
<style scoped>
#vpv {
  width: 100%;
  height: 1490px;
  margin: 0 auto;
}
</style>