Repository: sveltejs/svelte (JavaScript)
Task type: Feature

Issue:
Allow `anchor` to be passed in initial component instantiation
Hi, just started using svelte and I'm really liking it so far!

What do you think about allowing the initial config object to contain an `anchor` attribute so the component could be bootstrapped at a particular place in the dom?

In practice it would look something like this:

```javascript
const target = document.querySelector('main');
const anchor = target.getElementById('somechild');
const app = new App({
	target,
	anchor,
	data: { name: 'yo yo' }
});
```

I have this [working in my fork](https://github.com/amwmedia/svelte/commit/9dbc571f57be5cfe00b720210b08533bcf8606f9), the change is incredibly small.

Thanks!


Discussion:

Solution patch:
diff --git a/src/generators/dom/index.ts b/src/generators/dom/index.ts
--- a/src/generators/dom/index.ts
+++ b/src/generators/dom/index.ts
@@ -213,7 +213,7 @@ export default function dom(
 						${options.dev && `if ( options.hydrate ) throw new Error( 'options.hydrate only works if the component was compiled with the \`hydratable: true\` option' );`}
 						this._fragment.create();
 					`}
-				this._fragment.${block.hasIntroMethod ? 'intro' : 'mount'}( options.target, null );
+				this._fragment.${block.hasIntroMethod ? 'intro' : 'mount'}( options.target, options.anchor || null );
 			}
 
 			${(generator.hasComponents || generator.hasComplexBindings || templateProperties.oncreate || generator.hasIntroTransitions) && deindent`


Test patch:
diff --git a/test/js/samples/collapses-text-around-comments/expected-bundle.js b/test/js/samples/collapses-text-around-comments/expected-bundle.js
--- a/test/js/samples/collapses-text-around-comments/expected-bundle.js
+++ b/test/js/samples/collapses-text-around-comments/expected-bundle.js
@@ -237,7 +237,7 @@ function SvelteComponent ( options ) {
 
 	if ( options.target ) {
 		this._fragment.create();
-		this._fragment.mount( options.target, null );
+		this._fragment.mount( options.target, options.anchor || null );
 	}
 }
 
diff --git a/test/js/samples/collapses-text-around-comments/expected.js b/test/js/samples/collapses-text-around-comments/expected.js
--- a/test/js/samples/collapses-text-around-comments/expected.js
+++ b/test/js/samples/collapses-text-around-comments/expected.js
@@ -73,7 +73,7 @@ function SvelteComponent ( options ) {
 
 	if ( options.target ) {
 		this._fragment.create();
-		this._fragment.mount( options.target, null );
+		this._fragment.mount( options.target, options.anchor || null );
 	}
 }
 
diff --git a/test/js/samples/computed-collapsed-if/expected-bundle.js b/test/js/samples/computed-collapsed-if/expected-bundle.js
--- a/test/js/samples/computed-collapsed-if/expected-bundle.js
+++ b/test/js/samples/computed-collapsed-if/expected-bundle.js
@@ -184,7 +184,7 @@ function SvelteComponent ( options ) {
 
 	if ( options.target ) {
 		this._fragment.create();
-		this._fragment.mount( options.target, null );
+		this._fragment.mount( options.target, options.anchor || null );
 	}
 }
 
diff --git a/test/js/samples/computed-collapsed-if/expected.js b/test/js/samples/computed-collapsed-if/expected.js
--- a/test/js/samples/computed-collapsed-if/expected.js
+++ b/test/js/samples/computed-collapsed-if/expected.js
@@ -44,7 +44,7 @@ function SvelteComponent ( options ) {
 
 	if ( options.target ) {
 		this._fragment.create();
-		this._fragment.mount( options.target, null );
+		this._fragment.mount( options.target, options.anchor || null );
 	}
 }
 
diff --git a/test/js/samples/css-media-query/expected-bundle.js b/test/js/samples/css-media-query/expected-bundle.js
--- a/test/js/samples/css-media-query/expected-bundle.js
+++ b/test/js/samples/css-media-query/expected-bundle.js
@@ -219,7 +219,7 @@ function SvelteComponent ( options ) {
 
 	if ( options.target ) {
 		this._fragment.create();
-		this._fragment.mount( options.target, null );
+		this._fragment.mount( options.target, options.anchor || null );
 	}
 }
 
diff --git a/test/js/samples/css-media-query/expected.js b/test/js/samples/css-media-query/expected.js
--- a/test/js/samples/css-media-query/expected.js
+++ b/test/js/samples/css-media-query/expected.js
@@ -59,7 +59,7 @@ function SvelteComponent ( options ) {
 
 	if ( options.target ) {
 		this._fragment.create();
-		this._fragment.mount( options.target, null );
+		this._fragment.mount( options.target, options.anchor || null );
 	}
 }
 
diff --git a/test/js/samples/each-block-changed-check/expected-bundle.js b/test/js/samples/each-block-changed-check/expected-bundle.js
--- a/test/js/samples/each-block-changed-check/expected-bundle.js
+++ b/test/js/samples/each-block-changed-check/expected-bundle.js
@@ -331,7 +331,7 @@ function SvelteComponent ( options ) {
 
 	if ( options.target ) {
 		this._fragment.create();
-		this._fragment.mount( options.target, null );
+		this._fragment.mount( options.target, options.anchor || null );
 	}
 }
 
diff --git a/test/js/samples/each-block-changed-check/expected.js b/test/js/samples/each-block-changed-check/expected.js
--- a/test/js/samples/each-block-changed-check/expected.js
+++ b/test/js/samples/each-block-changed-check/expected.js
@@ -158,7 +158,7 @@ function SvelteComponent ( options ) {
 
 	if ( options.target ) {
 		this._fragment.create();
-		this._fragment.mount( options.target, null );
+		this._fragment.mount( options.target, options.anchor || null );
 	}
 }
 
diff --git a/test/js/samples/event-handlers-custom/expected-bundle.js b/test/js/samples/event-handlers-custom/expected-bundle.js
--- a/test/js/samples/event-handlers-custom/expected-bundle.js
+++ b/test/js/samples/event-handlers-custom/expected-bundle.js
@@ -228,7 +228,7 @@ function SvelteComponent ( options ) {
 
 	if ( options.target ) {
 		this._fragment.create();
-		this._fragment.mount( options.target, null );
+		this._fragment.mount( options.target, options.anchor || null );
 	}
 }
 
diff --git a/test/js/samples/event-handlers-custom/expected.js b/test/js/samples/event-handlers-custom/expected.js
--- a/test/js/samples/event-handlers-custom/expected.js
+++ b/test/js/samples/event-handlers-custom/expected.js
@@ -68,7 +68,7 @@ function SvelteComponent ( options ) {
 
 	if ( options.target ) {
 		this._fragment.create();
-		this._fragment.mount( options.target, null );
+		this._fragment.mount( options.target, options.anchor || null );
 	}
 }
 
diff --git a/test/js/samples/if-block-no-update/expected-bundle.js b/test/js/samples/if-block-no-update/expected-bundle.js
--- a/test/js/samples/if-block-no-update/expected-bundle.js
+++ b/test/js/samples/if-block-no-update/expected-bundle.js
@@ -270,7 +270,7 @@ function SvelteComponent ( options ) {
 
 	if ( options.target ) {
 		this._fragment.create();
-		this._fragment.mount( options.target, null );
+		this._fragment.mount( options.target, options.anchor || null );
 	}
 }
 
diff --git a/test/js/samples/if-block-no-update/expected.js b/test/js/samples/if-block-no-update/expected.js
--- a/test/js/samples/if-block-no-update/expected.js
+++ b/test/js/samples/if-block-no-update/expected.js
@@ -106,7 +106,7 @@ function SvelteComponent ( options ) {
 
 	if ( options.target ) {
 		this._fragment.create();
-		this._fragment.mount( options.target, null );
+		this._fragment.mount( options.target, options.anchor || null );
 	}
 }
 
diff --git a/test/js/samples/if-block-simple/expected-bundle.js b/test/js/samples/if-block-simple/expected-bundle.js
--- a/test/js/samples/if-block-simple/expected-bundle.js
+++ b/test/js/samples/if-block-simple/expected-bundle.js
@@ -246,7 +246,7 @@ function SvelteComponent ( options ) {
 
 	if ( options.target ) {
 		this._fragment.create();
-		this._fragment.mount( options.target, null );
+		this._fragment.mount( options.target, options.anchor || null );
 	}
 }
 
diff --git a/test/js/samples/if-block-simple/expected.js b/test/js/samples/if-block-simple/expected.js
--- a/test/js/samples/if-block-simple/expected.js
+++ b/test/js/samples/if-block-simple/expected.js
@@ -82,7 +82,7 @@ function SvelteComponent ( options ) {
 
 	if ( options.target ) {
 		this._fragment.create();
-		this._fragment.mount( options.target, null );
+		this._fragment.mount( options.target, options.anchor || null );
 	}
 }
 
diff --git a/test/js/samples/legacy-input-type/expected-bundle.js b/test/js/samples/legacy-input-type/expected-bundle.js
--- a/test/js/samples/legacy-input-type/expected-bundle.js
+++ b/test/js/samples/legacy-input-type/expected-bundle.js
@@ -204,7 +204,7 @@ function SvelteComponent ( options ) {
 
 	if ( options.target ) {
 		this._fragment.create();
-		this._fragment.mount( options.target, null );
+		this._fragment.mount( options.target, options.anchor || null );
 	}
 }
 
diff --git a/test/js/samples/legacy-input-type/expected.js b/test/js/samples/legacy-input-type/expected.js
--- a/test/js/samples/legacy-input-type/expected.js
+++ b/test/js/samples/legacy-input-type/expected.js
@@ -46,7 +46,7 @@ function SvelteComponent ( options ) {
 
 	if ( options.target ) {
 		this._fragment.create();
-		this._fragment.mount( options.target, null );
+		this._fragment.mount( options.target, options.anchor || null );
 	}
 }
 
diff --git a/test/js/samples/non-imported-component/expected-bundle.js b/test/js/samples/non-imported-component/expected-bundle.js
--- a/test/js/samples/non-imported-component/expected-bundle.js
+++ b/test/js/samples/non-imported-component/expected-bundle.js
@@ -226,7 +226,7 @@ function SvelteComponent ( options ) {
 
 	if ( options.target ) {
 		this._fragment.create();
-		this._fragment.mount( options.target, null );
+		this._fragment.mount( options.target, options.anchor || null );
 	}
 
 	if ( !options._root ) {
diff --git a/test/js/samples/non-imported-component/expected.js b/test/js/samples/non-imported-component/expected.js
--- a/test/js/samples/non-imported-component/expected.js
+++ b/test/js/samples/non-imported-component/expected.js
@@ -74,7 +74,7 @@ function SvelteComponent ( options ) {
 
 	if ( options.target ) {
 		this._fragment.create();
-		this._fragment.mount( options.target, null );
+		this._fragment.mount( options.target, options.anchor || null );
 	}
 
 	if ( !options._root ) {
diff --git a/test/js/samples/onrender-onteardown-rewritten/expected-bundle.js b/test/js/samples/onrender-onteardown-rewritten/expected-bundle.js
--- a/test/js/samples/onrender-onteardown-rewritten/expected-bundle.js
+++ b/test/js/samples/onrender-onteardown-rewritten/expected-bundle.js
@@ -191,7 +191,7 @@ function SvelteComponent ( options ) {
 
 	if ( options.target ) {
 		this._fragment.create();
-		this._fragment.mount( options.target, null );
+		this._fragment.mount( options.target, options.anchor || null );
 	}
 
 	if ( !options._root ) {
diff --git a/test/js/samples/onrender-onteardown-rewritten/expected.js b/test/js/samples/onrender-onteardown-rewritten/expected.js
--- a/test/js/samples/onrender-onteardown-rewritten/expected.js
+++ b/test/js/samples/onrender-onteardown-rewritten/expected.js
@@ -51,7 +51,7 @@ function SvelteComponent ( options ) {
 
 	if ( options.target ) {
 		this._fragment.create();
-		this._fragment.mount( options.target, null );
+		this._fragment.mount( options.target, options.anchor || null );
 	}
 
 	if ( !options._root ) {
diff --git a/test/js/samples/setup-method/expected-bundle.js b/test/js/samples/setup-method/expected-bundle.js
--- a/test/js/samples/setup-method/expected-bundle.js
+++ b/test/js/samples/setup-method/expected-bundle.js
@@ -193,7 +193,7 @@ function SvelteComponent ( options ) {
 
 	if ( options.target ) {
 		this._fragment.create();
-		this._fragment.mount( options.target, null );
+		this._fragment.mount( options.target, options.anchor || null );
 	}
 }
 
diff --git a/test/js/samples/setup-method/expected.js b/test/js/samples/setup-method/expected.js
--- a/test/js/samples/setup-method/expected.js
+++ b/test/js/samples/setup-method/expected.js
@@ -53,7 +53,7 @@ function SvelteComponent ( options ) {
 
 	if ( options.target ) {
 		this._fragment.create();
-		this._fragment.mount( options.target, null );
+		this._fragment.mount( options.target, options.anchor || null );
 	}
 }
 
diff --git a/test/js/samples/use-elements-as-anchors/expected-bundle.js b/test/js/samples/use-elements-as-anchors/expected-bundle.js
--- a/test/js/samples/use-elements-as-anchors/expected-bundle.js
+++ b/test/js/samples/use-elements-as-anchors/expected-bundle.js
@@ -430,7 +430,7 @@ function SvelteComponent ( options ) {
 
 	if ( options.target ) {
 		this._fragment.create();
-		this._fragment.mount( options.target, null );
+		this._fragment.mount( options.target, options.anchor || null );
 	}
 }
 
diff --git a/test/js/samples/use-elements-as-anchors/expected.js b/test/js/samples/use-elements-as-anchors/expected.js
--- a/test/js/samples/use-elements-as-anchors/expected.js
+++ b/test/js/samples/use-elements-as-anchors/expected.js
@@ -266,7 +266,7 @@ function SvelteComponent ( options ) {
 
 	if ( options.target ) {
 		this._fragment.create();
-		this._fragment.mount( options.target, null );
+		this._fragment.mount( options.target, options.anchor || null );
 	}
 }