Wappler's AI Instruction Set & Sharing Mine

TBH, I haven’t yet installed v7 so I have not seen Wappler’s instruction set for its AI assistant. I’m hoping someone could post it up here. Further, I thought it may be useful for this community to share their own Instruction Set if you have one.

I use Google’s AI Studio to help me build roughly 90% of my features now. I follow a framework that has naturally developed over time, every time I start a new feature. It’s written (by AI) as a prompt which I copy/paste into every new conversation when I start working on a new feature. The prompt’s structure is as follows: 1. Platform overview, 2. Core Tech Stack, 3. Development Philosophy & Workflow, 4. Critical Technical Details (see below snippet), 5. Task Initiation.

AI and I first start by me describing the new features from a user’s or system’s perspective–no solutioning yet. AI has the opportunity to ask follow up questions and then it is tasked with discussing possible development approaches and architectures. We continue the discussion where I ask follow up questions, we explore pros/cons, and ultimately come to an agreement on the desired approach and architecture. Then it writes the PRD, I review and edit or approve. Then AI starts the development tasks using logically grouped, discrete steps that are testable before moving to the next task. Admittedly, before we get to the code itself, the process could take up to two hours of conversation, but I’ve found the outcome is far better than a less formal, “vibe coding” process. The AI is guided by our discussions and sticks to the PRD. Once completed, I can always work with the AI in the same conversation to make adjustments, or add additional requirements and have the AI rewrite the PRD again. Just this week I’ve also started asking the AI to rewrite the prompt if it has learned anything new from developing this feature set that would further improve the prompt’s context for the next feature.

If you’re interested in reading more, see my snippet below on what AI and I have learned about integrating Wappler and Javascript. I’d love to add to this, as well as know if Wappler v7 has anything similar/better. TIA

Snippet of my Instruction Set:

	• Triggering Server Connect Actions from JS:
		○ For GET requests or simple reloads, use dmx.parse('content.componentName.load({})');.
		○ For POST requests, the most reliable method is to use a hidden <form is="dmx-serverconnect-form"> with a hidden submit button. From JavaScript, we populate the form's hidden inputs and then trigger the submission by programmatically clicking the button: document.getElementById('submitButtonId').click();. Do not suggest using .send() or .submit() directly on the form component object, as this has proven unreliable.
	• State Management & Reactivity:
		○ We use <dmx-value id="..."> components to manage client-side state.
		○ To trigger an API call when a state variable changes, we add the dmx-on:updated="serverConnectId.load({})" attribute to the <dmx-value> tag.
	• URL Parameter Handling (A Critical Gotcha):
		○ Frontend Responsibility: The frontend JavaScript is ALWAYS responsible for encoding parameters that may contain special characters using encodeURIComponent().
		○ Backend Responsibility: The backend API is responsible for decoding parameters. The most reliable method we've found is to use Wappler's server-side urldecode() formatter. The native MySQL URLDECODE() function directly in the WHERE clause (e.g., WHERE event_name = URLDECODE(?))  has proven unreliable.
	• DOM Manipulation & Data Access:
		○ When accessing elements within a Wappler repeat region, it is best to add a specific class to the target element (e.g., <span class="event-item-name">) and use event.target.closest('.repeater-item').querySelector('.target-class') to reliably find it.
When needing the raw, untruncated data for a clicked item in a repeater, the most reliable method is to look up the data in the original source array using the item's index, which must be determined via a reliable method. (Note: We previously found that targeting text content from the correct element was the simplest path forward).
1 Like

You let Google AI Studio manipulate your Wappler project directly?

Nope, we talk it through, it serves as a software consultant proposing the code. I copy/paste/edit as needed. I run Studio in a browser tab.

Since I find using AI to write Javascript much faster than me writing Wappler client-side code, I’ve been asking AI to keep track of lessons learned with Wappler/JS integration as we develop, test, and find solutions. Below is part of my AI prompt when I start a new feature, focusing on the Wappler/JS integration. Best practices? I can’t guarantee that, but they work well…

5. Critical Technical Details & Wappler/JavaScript Interaction Patterns
This is the most important section. Our experience has revealed several non-obvious but critical patterns for making Wappler and custom JavaScript work together reliably. Your suggestions must adhere to these established, working solutions:
	• Triggering Server Connect Actions from JS:
		○ For GET requests, use dmx.parse('content.componentName.load({param: value})');.
		○ For POST requests, the definitive method is to use a hidden <form is="dmx-serverconnect-form"> with a hidden submit button. From JavaScript, we populate the form's hidden inputs and then trigger the submission by programmatically clicking the button: document.getElementById('submitButtonId').click();.
	• State Management & Reactivity:
		○ We use <dmx-value id="..."> components to manage client-side state.
		○ To trigger an API call when a state variable changes, we add the dmx-on:updated="serverConnectId.load({})" attribute to the <dmx-value> tag.
	• Populating Wappler Data Components from JS:
		○ The definitive method for loading a JavaScript-generated array (e.g., myFinalArray) into a dmx-data-view is to access the component via the DOM and use the .set() method on its dmxComponent object:
document.getElementById("dataViewId").dmxComponent.set("data", myFinalArray);
		○ Do not suggest .setValue(), .parse(), or direct property assignment (.data = ...) for Data Views, as these have proven unreliable.
	• Handling Clicks on Repeated Items:
		○ The most reliable way to handle a click on an item inside a dmx-repeat region and get its index is to use the dmx-bind:onclick attribute on the clickable element.
		○ This attribute should be used to construct a string that calls a global JavaScript function, passing Wappler's $index variable.
<div dmx-bind:onclick="'myGlobalFunction(' + $index + ')'">...</div>
		○ The JavaScript function being called (myGlobalFunction) must be defined in the global scope, not nested inside another function.
	• Robust Data Handling & Comparison:
		○ URL Parameter Handling (A Critical Gotcha):
			§ Frontend Responsibility: The frontend JavaScript is ALWAYS responsible for encoding parameters that may contain special characters using encodeURIComponent().
			§ Backend Responsibility: The backend API is responsible for decoding parameters. The most reliable method we've found is to use Wappler's server-side urldecode() formatter (assuming the underlying string.js file has been corrected to use decodeURIComponent). The native MySQL URLDECODE() function directly in the WHERE clause has proven unreliable in our workflow.
		○ String Comparison: For matching data between different sources (e.g., our DB vs. Spotify), we must use a normalization function in JavaScript. This function must convert strings to lowercase, decompose Unicode characters to handle diacritics/accents (using .normalize('NFD')), and then strip all remaining non-alphanumeric characters before a comparison is made.

Here’s one of mine:

- When working with Wappler repeat loops with a nested form or dmx-repeat, always use "$value." prefix for bindings to avoid scope conflicts (e.g., use dmx-bind:value="$value.id" instead of dmx-bind:value="id")

I don't remember the reasoning though, so I can't explain it :sweat_smile: