diff --git a/assets/js/app-demo.ts b/assets/js/app-demo.ts
index 569874e..2cec778 100644
--- a/assets/js/app-demo.ts
+++ b/assets/js/app-demo.ts
@@ -1,7 +1,7 @@
 // app-demo.ts - petite-vue application using dummy localStorage backend
 
 import { createApp } from 'petite-vue'
-import { Config, register, handle, createRandString, sleep} from './common'
+import { Config, register, handle, createRandString} from './common'
 
 export const pvapp = {
 	run(conf: Config, components: any[]) {
@@ -27,7 +27,6 @@ const store_prefix = 'api.storage'
 // methods
 
 async function sendMsg(basemsg: string[], data: any) {
-	await sleep(50)
 	const [ domain, action, class_, item ] = basemsg
 	switch (action) {
 		case 'data':
diff --git a/assets/js/common.ts b/assets/js/common.ts
index 95d0174..db8fac8 100644
--- a/assets/js/common.ts
+++ b/assets/js/common.ts
@@ -13,9 +13,11 @@ export type Config = {
 
 export function config (api): Config {
 	const pu = api.polling ? `${api.path}/${api.polling.msgbase.join('/')}` : ''
+	const urlparams = new URL(location.href).searchParams
 	return { 
 		domain: domain,
-		itemid: location.hash.substring(1),
+		//itemid: location.hash.substring(1),
+		itemid: urlparams.get('id'),
 		sid: getSid(),
 		iid: createRandString(1),
 		apiurl: api.path, 
@@ -27,6 +29,7 @@ export function config (api): Config {
 
 export function register(name: string, comp: any) {
 	this.components[name] = comp
+	comp.initialize()
 }
 
 // common functions
@@ -34,12 +37,13 @@ export function register(name: string, comp: any) {
 export function handle(app, msg) {
 	const [ domain, action, class_, item ] = msg.path.split('/')
 	const comp = app.components[class_ || 'data']
+	if (!comp) {
+		msg.log(`**** handle: component ${class_} not found.`)
+	}
 	if (domain && domain !== comp.domain) {
 		return
 	}
-	if (comp) {
-		comp.handle(domain, action, class_, item, msg.payload)
-	}
+	comp.handle(domain, action, class_, item, msg.payload)
 }
 
 export function createRandString(size: number): string {
diff --git a/assets/js/comp-data.ts b/assets/js/comp-data.ts
index 2f44bf1..91f0243 100644
--- a/assets/js/comp-data.ts
+++ b/assets/js/comp-data.ts
@@ -12,21 +12,25 @@ export function Data(name: string, conf: any): object {
 		domain: domain, // domain of incoming/outgoing message
 		data: {}, 	// model (2-way data store)
 		meta: {},	// metadata (params) for each data field
+		initialize,
 		handle,		// handle incoming messages
 		exec,		// default function to execute upon button click
-		initField,	// initialize field (= @mounted)
+		initField,	// initialize field (= @mounted), collect metadata
 		chmode,
 		copynew
 	}
 	//this.components[name] = comp
-	if (comp.state.id) {
-		this.sendMsg([domain, 'query', name, comp.state.id], {})
-	}
 	return comp
 }
 
 // Data methods
 
+function initialize() {
+	if (this.state.id) {
+		this.sendMsg([this.domain, 'query', this.name, this.state.id], {})
+	}
+}
+
 function handle(domain, action, class_, item, payload: string) {
 	const data = JSON.parse(payload)
 	console.log('handle - action: ', action, ', data: ', data)
@@ -35,8 +39,9 @@ function handle(domain, action, class_, item, payload: string) {
 		this.state.mode = 'view'
 	} else if (action === 'response') { // && data.rc == 3) {
 		this.state.id = item
-		window.location.hash = item
-		this.sendMsg([this.domain, 'query', this.name, item], {})
+		//window.location.hash = item
+		window.location.assign(`?id=${item}`)
+		//this.sendMsg([this.domain, 'query', this.name, item], {})
 	}
 }
 
diff --git a/assets/js/comp-list.ts b/assets/js/comp-list.ts
index ae77824..8881c2f 100644
--- a/assets/js/comp-list.ts
+++ b/assets/js/comp-list.ts
@@ -12,16 +12,19 @@ export function List(name: string, conf: any): object {
 		domain: domain, // domain of incoming/outgoing message
 		data: [], 	// model = list of rows
 		meta: {},	// metadata (params) for each field (table column)
+		initialize,
 		handle,		// handle incoming messages
 		initField	// initialize field (= @mounted)
 	}
-	//this.components[name] = comp
-	this.sendMsg([domain, 'query', name], {})
 	return comp
 }
 
 // Data methods
 
+function initialize() {
+	this.sendMsg([this.domain, 'query', this.name], {})
+}
+
 function handle(domain, action, class_, item: string, payload) {
 	if (action == 'list') {
 		const rows = payload.split('\n')
diff --git a/exampleSite/content/app/login.md b/exampleSite/content/app/login.md
index a5a0f7b..0b32836 100644
--- a/exampleSite/content/app/login.md
+++ b/exampleSite/content/app/login.md
@@ -5,23 +5,22 @@ img:
 pageid: app-login
 domains: [App]
 topics: [Examples]
-date:   2023-03-14
-author: helmutm
+date:   2023-03-27
 draft:  false
-weight: 100
+weight: 400
 api:
   domain: system
 ---
 
 cyberscopes example site - Login Form
 
-{{< pv/fieldset name="login" >}}
+{{< pv/data name="login" >}}
 
-  Login: {{< pv/input-textline name="login" attrs="autofocus" >}}
-  Password: {{< pv/input-textline type="password" name="password" >}}
+  Login: {{< pv/data-field-line name="login" attrs="autofocus" >}}
+  Password: {{< pv/data-field-line type="password" name="password" >}}
   {{< pv/button label="Login" action="login" >}}
 
-{{< /pv/fieldset >}}
+{{< /pv/data >}}
 
 ---
 
diff --git a/exampleSite/content/app/person-list.md b/exampleSite/content/app/person-list.md
index 25e018e..4a29ebd 100644
--- a/exampleSite/content/app/person-list.md
+++ b/exampleSite/content/app/person-list.md
@@ -5,8 +5,7 @@ img:
 pageid: app_list_person
 domains: [App]
 topics: [Examples]
-date:   2023-03-22
-author: helmutm
+date:   2023-03-27
 draft:  false
 weight: 100
 ---
diff --git a/exampleSite/content/app/person.md b/exampleSite/content/app/person.md
index 8bbe1cc..f461c34 100644
--- a/exampleSite/content/app/person.md
+++ b/exampleSite/content/app/person.md
@@ -5,21 +5,20 @@ img:
 pageid: app_form_person
 domains: [App]
 topics: [Examples]
-date:   2023-03-19
-author: helmutm
+date:   2023-03-27
 draft:  false
 weight: 100
 ---
 
 cyberscopes example site - view / edit person (user) data.
 
-{{< pv/fieldset name="person" >}}
+{{< pv/data name="person" >}}
 
-  {{< pv/tabs-mode >}}
+  {{< pv/data-tabs >}}
 
-  First Name: {{< pv/input-textline name="firstname" attrs="autofocus" >}}
-  Last Name: {{< pv/input-textline name="lastname" >}}
-  Email: {{< pv/input-textline name="email" default="hm@cy55.de" >}}
+  First Name: {{< pv/data-field-line name="firstname" attrs="autofocus" >}}
+  Last Name: {{< pv/data-field-line name="lastname" >}}
+  Email: {{< pv/data-field-line name="email" default="hm@cy55.de" >}}
 
   {{< pv/button mode="edit" label="Save Changes" >}}
   {{< pv/button mode="edit" exec="copynew" label="Copy Data" >}}
@@ -27,14 +26,15 @@ cyberscopes example site - view / edit person (user) data.
   {{< pv/button mode="new" label="Create Item" >}}
 
 
-  {{< pv/display linkto="state.id"
+  {{< pv/data-display
         expr="`${data.firstname} ${data.lastname}`.trim() || '???'" >}}
+  {{< pv/data-display expr="state.id ? ` (Id: ${state.id})` : ''" >}} 
 
   {{< pv/link >}}
-    Reload page with id {{< pv/display expr="state.id" >}}
+    Reload page with id {{< pv/data-display expr="state.id" >}}
   {{< /pv/link >}}
 
-{{< /pv/fieldset >}}
+{{< /pv/data >}}
 
 {{< pv/debug >}}
 
diff --git a/exampleSite/content/app/test0.md b/exampleSite/content/app/test0.md
index da4cfac..89b4ae2 100644
--- a/exampleSite/content/app/test0.md
+++ b/exampleSite/content/app/test0.md
@@ -5,18 +5,17 @@ img:
 pageid: test0
 domains: [App]
 topics: [Examples]
-date:   2023-03-12
-author: helmutm
+date:   2023-03-27
 draft:  false
-weight: 110
+weight: 510
 ---
 
 cyberscopes example site - use petite-vue in Hugo-generated sites.
 
-{{< pv/count >}}
+{{< pv/xplore/count >}}
 
-{{< pv/count init="7" expr="count--" label="dec" >}}
+{{< pv/xplore/count init="7" expr="count--" label="dec" >}}
 
-{{< pv/count init="99" expr="save()" label="log" >}}
+{{< pv/xplore/count init="99" expr="save()" label="log" >}}
 
-{{< pv/explore >}}
+{{< pv/xplore/explore >}}
diff --git a/layouts/shortcodes/pv/display.html b/layouts/shortcodes/pv/data-display.html
similarity index 54%
rename from layouts/shortcodes/pv/display.html
rename to layouts/shortcodes/pv/data-display.html
index 3051095..6ecec1e 100644
--- a/layouts/shortcodes/pv/display.html
+++ b/layouts/shortcodes/pv/data-display.html
@@ -1,6 +1,3 @@
 {{- $name := .Get "name" | default "textline" -}}
 {{- $expr := .Get "expr" | default (printf "data.%s" $name) -}}
-{{- $linkto := .Get "linkto" -}}
-{{- if $linkto }}{{ end -}}
 
-{{- if $linkto }}{{ end -}}
diff --git a/layouts/shortcodes/pv/input-textline.html b/layouts/shortcodes/pv/data-field-line.html
similarity index 100%
rename from layouts/shortcodes/pv/input-textline.html
rename to layouts/shortcodes/pv/data-field-line.html
diff --git a/layouts/shortcodes/pv/tabs-mode.md b/layouts/shortcodes/pv/data-tabs.html
similarity index 100%
rename from layouts/shortcodes/pv/tabs-mode.md
rename to layouts/shortcodes/pv/data-tabs.html
diff --git a/layouts/shortcodes/pv/fieldset.html b/layouts/shortcodes/pv/data.html
similarity index 100%
rename from layouts/shortcodes/pv/fieldset.html
rename to layouts/shortcodes/pv/data.html
diff --git a/layouts/shortcodes/pv/link.html b/layouts/shortcodes/pv/link.html
index c2cec8e..19d4de1 100644
--- a/layouts/shortcodes/pv/link.html
+++ b/layouts/shortcodes/pv/link.html
@@ -1,3 +1,3 @@
 {{- $target := .Get "target" | default "state.id" -}}
-{{- $prefix := .Get "prefix" | default "#" -}}
+{{- $prefix := .Get "prefix" | default "?id=" -}}
 {{ .Inner }}
diff --git a/layouts/shortcodes/pv/list.html b/layouts/shortcodes/pv/list.html
index 163cbd8..0b1d43d 100644
--- a/layouts/shortcodes/pv/list.html
+++ b/layouts/shortcodes/pv/list.html
@@ -10,7 +10,7 @@