Set content-type header

I’m trying to make a page where an uploaded PDF file in Kirby is shown on the page without any content. When I try ‘Content-disposition: attachment’. Everything works perfectly, but my client would rather not force a download but show the PDF inline when the browser supports this.

This seems not to work because Kirby CMS overrides the content-type back to text/html.

My code:

// Get file
$file = $page->files()->first();

// Output file
header('Content-Type: application/pdf');
header('Content-Transfer-Encoding: Binary');
header('Content-disposition: inline; filename='.$file->filename());
echo file_get_contents($file->root());

Even when trying the Header::contentType() function as stated in the manual, the content type gets reset each time the page is loaded:

// Get file
$file = $page->files()->first();

// Output file
Header::contentType('application/pdf', 'UTF-8', true);
//header('Content-Type: application/pdf');
header('Content-Transfer-Encoding: Binary');
header('Content-disposition: inline; filename='.$file->filename());
echo file_get_contents($file->root());

How can I force a PDF to be shown inline a page template?

Hmm an odd one. I dont know the answer but I would suggest using readfile() instead of file_get_contents since it uses half as much ram. readfile() copies straight to the output buffer, where as file_get_contents copies it to memory first, then to the buffer, which uses twice as much ram.

1 Like

Not sure if I understand correctly, but a normal link should open the file in the browser, depending on browser and user settings.

Edit: Where are you using the code you posted above?

I’m using this template in site/templates/file.php.

But let’s rephrase the question. I want to force Content-Type: application/pdf. I’ve tried what your manual said https://getkirby.com/docs/reference/tools/header/content-type by setting this in the top of my file:

Header::contentType('application/pdf', 'UTF-8', true);

That doesn’t seem to work. So I tried regular PHP headers:

header('Content-Type: application/pdf');

But that also doesn’t work. Kirby rewrites the Content-Type header to ‘text/html’ and thus forcing my PDF content to be unreadable. I’ve checked if other headers could be set, and these seem to work perfectly:

header('Content-Transfer-Encoding: Binary');
header('Content-disposition: inline; filename='.$file->filename());

Which means that the only conclusion I have right now is that Kirby forcefully rewrites the Content-Type headers. Why is this and how can I force my own headers, even when using the suggested PHP code from your manual?

I think you can avoid that by using a route instead of a template

Making a new route for something simple like only setting a different content-type header seems weird?

Anyway on the forum I’ve found that another user posted this code which seems to work directly in the template and thus resolves my issue:
$kirby->response()->code(200)->type('application/pdf');

Instead of either one of these:

header('Content-Type: application/pdf');
Header::contentType('application/pdf', 'UTF-8', true);
2 Likes