0

I have a Dialog in my vue project to display a PDF file. This is how the parent component handles the PDF file.

async function openDialog(index: number) {
  isLoading.value = true;
  const selectedEbook = listEbook.value[index];
  const originalUrl = selectedEbook.url;

  if (!originalUrl) {
    console.warn("URL tidak tersedia untuk item ini");
    isLoading.value = false;
    return;
  }

  const isDev = import.meta.env.MODE === "development";
  const fileUrl = isDev
    ? originalUrl.replace("https://main-url.com", "/api-pdf")
    : originalUrl;

  if (!fileUrl) return;

  try {
    const response = await axios.get(fileUrl, {
      responseType: "blob",
    });
    if (!response) throw new Error("Gagal fetch file PDF");

    if (selectedBlobUrl.value) {
      URL.revokeObjectURL(selectedBlobUrl.value);
    }

    // this condition to check the selectedEbook url, because there is 2 different url, 
    // the one is generated pdf from API and another one is static pdf from FTP server
    if (selectedEbook.icon != "pi-file-pdf") {
      const blob = new Blob([response.data], { type: "application/pdf" });
      selectedBlobUrl.value = URL.createObjectURL(blob);
    } else {
      const url = URL.createObjectURL(
        new Blob([response.data], {
          type: "application/pdf",
        })
      );
      selectedBlobUrl.value = url;
    }
    console.log(selectedBlobUrl.value);

    pdfDialog.value = true;
  } catch (err) {
    console.error("Gagal membuka PDF:", err);
  } finally {
    isLoading.value = false;
  }
}

And this is how the child component handles it

<template>
  <Dialog
    v-model:visible="visible"
    modal
    header="Lihat Dokumen"
    :style="{ width: '100%', height: '100%' }"
    :breakpoints="{ '1199px': '75vw', '575px': '90vw' }"
  >
    <VuePdfEmbed
      annotation-layer
      text-layer
      :source="props.url"
      class="shadow-3"
    />
  </Dialog>
</template>

<script setup lang="ts">
import { computed, watch } from "vue";
import VuePdfEmbed from "vue-pdf-embed";
import "vue-pdf-embed/dist/styles/annotationLayer.css";
import "vue-pdf-embed/dist/styles/textLayer.css";

const props = defineProps<{
  url: string | null;
  modelValue: boolean;
}>();

const emits = defineEmits<{
  (e: "update:modelValue", value: boolean): void;
}>();

const visible = computed({
  get: () => props.modelValue,
  set: (value) => emits("update:modelValue", value),
});

watch(
  () => props.url,
  (value) => {
    if (value) {
      // Handle the non-null value of props.url here
      console.log(value);
    }
  }
);
</script>

In development mode, the PDF is work properly. But in production, the PDF can't show on Dialog. What I have try is, actually i was using pdfjs-dist but then my friend suggested me to use vue-pdf-embed because I was using Vue in project. I appreciate for the answer

1 Answer 1

0

After some search, the answer is changing the Content-Dispotition from the response header of the PDF url from 'attachment' to 'inline'.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.