diff --git a/.changeset/little-boats-allow.md b/.changeset/little-boats-allow.md
new file mode 100644
index 000000000000..b40efda8414c
--- /dev/null
+++ b/.changeset/little-boats-allow.md
@@ -0,0 +1,5 @@
+---
+'@sveltejs/kit': patch
+---
+
+feat(config): Friendlier error messages for common errors
diff --git a/packages/kit/src/core/config/index.js b/packages/kit/src/core/config/index.js
index 8ccaad11d997..f162313ad282 100644
--- a/packages/kit/src/core/config/index.js
+++ b/packages/kit/src/core/config/index.js
@@ -13,6 +13,17 @@ import options from './options.js';
* @returns {any}
*/
function validate(definition, option, keypath) {
+ if (typeof option !== 'object') {
+ if (typeof option === 'undefined') {
+ throw new Error(
+ 'Your config is missing default exports. Make sure to include "export default config;"'
+ );
+ } else {
+ throw new Error(
+ `Unexpected config type "${typeof option}", make sure your default export is an object.`
+ );
+ }
+ }
for (const key in option) {
if (!(key in definition)) {
let message = `Unexpected option ${keypath}.${key}`;
diff --git a/packages/kit/src/core/config/test/fixtures/export-missing/src/app.html b/packages/kit/src/core/config/test/fixtures/export-missing/src/app.html
new file mode 100644
index 000000000000..245305c4ef5b
--- /dev/null
+++ b/packages/kit/src/core/config/test/fixtures/export-missing/src/app.html
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+ %svelte.head%
+
+
+ %svelte.body%
+
+
diff --git a/packages/kit/src/core/config/test/fixtures/export-missing/svelte.config.js b/packages/kit/src/core/config/test/fixtures/export-missing/svelte.config.js
new file mode 100644
index 000000000000..e69de29bb2d1
diff --git a/packages/kit/src/core/config/test/fixtures/export-string/src/app.html b/packages/kit/src/core/config/test/fixtures/export-string/src/app.html
new file mode 100644
index 000000000000..245305c4ef5b
--- /dev/null
+++ b/packages/kit/src/core/config/test/fixtures/export-string/src/app.html
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+ %svelte.head%
+
+
+ %svelte.body%
+
+
diff --git a/packages/kit/src/core/config/test/fixtures/export-string/svelte.config.js b/packages/kit/src/core/config/test/fixtures/export-string/svelte.config.js
new file mode 100644
index 000000000000..96089dcb0134
--- /dev/null
+++ b/packages/kit/src/core/config/test/fixtures/export-string/svelte.config.js
@@ -0,0 +1 @@
+export default 'invalid';
diff --git a/packages/kit/src/core/config/test/index.js b/packages/kit/src/core/config/test/index.js
index 4e8eea7dc3c1..87d4f0af57d9 100644
--- a/packages/kit/src/core/config/test/index.js
+++ b/packages/kit/src/core/config/test/index.js
@@ -71,4 +71,34 @@ test('load default config (esm)', async () => {
await testLoadDefaultConfig('default-esm');
});
+test('errors on loading config without default export', async () => {
+ let errorMessage = null;
+ try {
+ const cwd = join(__dirname, 'fixtures', 'export-missing');
+ await load_config({ cwd });
+ } catch (e) {
+ errorMessage = e.message;
+ }
+
+ assert.equal(
+ errorMessage,
+ 'Your config is missing default exports. Make sure to include "export default config;"'
+ );
+});
+
+test('errors on loading config with incorrect default export', async () => {
+ let errorMessage = null;
+ try {
+ const cwd = join(__dirname, 'fixtures', 'export-string');
+ await load_config({ cwd });
+ } catch (e) {
+ errorMessage = e.message;
+ }
+
+ assert.equal(
+ errorMessage,
+ 'Unexpected config type "string", make sure your default export is an object.'
+ );
+});
+
test.run();