How to Properly Read a Static File in SvelteKit Using a Server-Side Load Function?

I am working on a SvelteKit project where I want to dynamically render HTML content based on a route parameter (e.g., /2023, /2022). I have static HTML files (2012.html, 2013.html, etc.) stored in the src/assets directory, and I’m trying to read them in the +page.server.ts file using the fetch API.

What I Am Trying to Achieve

For each route like /2023 or /2022, I want to dynamically load an HTML file corresponding to the year from the server and render it on the page. For example, navigating to /2023 should fetch 2023.html from the src/assets or any folder and display its content. I just would like to avoid using static/ folder because I dont want to expose html like that and i do want users to visit proper svelte page.

My Setup

Here is my server-side load function in +page.server.ts:

import type { PageServerLoad } from './$types';

export const load: PageServerLoad = async ({ params, fetch }) => {
  try {
    // Use fetch to get the HTML content from the server
    console.log(params.year) //works e.g."2012"
    const {year} = params
    const response = await fetch(`src/assets/${year}.html`); // what is the proper method to get file?

    // Check if the response is OK (status 200-299)
    if (!response.ok) {
      console.error(`Error fetching the HTML file: ${response.status} ${response.statusText}`);
      return { dom: { html: '' } };
    }

    // Read the response as text
    const html = await response.text();

    // Log the HTML content for debugging
    console.log('HTML content:', html);

    return {
      dom: { html },
    };
  } catch (error) {
    console.error('Error reading the HTML file:', error);
    return {
      dom: { html: '' }, // Return empty string on any error
    };
  }
};

And my corresponding Svelte page component +page.svelte looks like this:

<script lang="ts">
  import type { PageData } from './$types';

  export let data: PageData;
</script>

<pre>{JSON.stringify(data, null, 2)}</pre>

The Problem

When I try to access any of the routes, I consistently get a 500 Internal Server Error. Here are the logs I receive on each reload:

Error fetching the HTML file: 500 Internal Server Error
Error fetching the HTML file: 500 Internal Server Error
2:28:49 AM [vite] page reload src/routes/[year]/+page.server.ts
Error fetching the HTML file: 500 Internal Server Error

Files can be dynamically imported. For certain file types there already is a handler, e.g. images are imported as URLs to an asset, but there also are query params to instruct Vite how to import.

Here you could just import the contents directly using ?raw like this:

const file = await import(`../../assets/${year}.html?raw`)
    .then(m => m.default);

(Not sure if aliases can be used, tried using $lib and that did not seem to work.)

If you make the route just a standalone +server.ts endpoint (no +page.svelte), you can return the contents using text:

// routes/[year]/+server.ts
import { text, type RequestHandler } from '@sveltejs/kit';

export const GET = (async ({ params }) => {
    const file = await import(`../../assets/${params.year}.html?raw`)
        .then(m => m.default);

    return text(file, {
        headers: {
            'Content-Type': 'text/html',
        },
    });
}) satisfies RequestHandler;

As pointed out by Peppe L-G, the ?raw import transforms the contents to a string in JS, which has some overhead and prevents more direct streaming to the client. An alternative might be using an ?url import in combination with read which should be equivalent to Peppe’s answer.

If you don’t transform the HTML or add other route-specific logic, you might as well use the static directory instead.

6

I’m not sure if this will work, but it’s a too long answer to suggest as a comment, so I write it as an answer. I hope it will work ^^’

  1. In vite.config.js, configure assetsInclude to include HTML files
  2. In your +page.server.ts file:
    • Import all of your HTML files (doesn’t matter where in your project you place the HTML files, thanks to (1))
    • In the load() function, use read() to send back the HTML file you want that you imported
    • I’m guessing you also need to set the Content-Type header in the response to text/html

The links that leads to these routes probably also needs to include target="_self", so SvelteKit doesn’t try to load them as ordinary routes, but does a full page load.

read() in SvelteKit is quite poorly documented IMO, see https://www.youtube.com/watch?v=m4G-6dyF1MU&t=67s to learn more about it.


HOWEVER, this is just a very complicated way of doing:

I just would like to avoid using static/ folder because I dont want to expose html like that and i do want users to visit proper svelte page.

So I’m not sure why you really would prefer doing it like this :/

3

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật