@@ -33,6 +33,7 @@ This comprehensive guide covers everything developers need to know to integrate,
3333 - [ YASQE Configuration] ( #yasqe-configuration )
3434 - [ YASQE Example] ( #yasqe-example )
3535 - [ Code Snippets] ( #code-snippets )
36+ - [ Share Configuration] ( #share-configuration )
3637 - [ YASR Configuration] ( #yasr-configuration )
3738 - [ YASR Example] ( #yasr-example )
3839 - [ Request Configuration] ( #request-configuration )
@@ -920,6 +921,314 @@ const yasqe = new Yasqe(document.getElementById('yasqe'), {
920921});
921922```
922923
924+ #### Share Configuration
925+
926+ Configure how users can share their SPARQL queries with multiple output formats including URLs, cURL, PowerShell, and wget commands.
927+
928+ ** Configuration Options:**
929+
930+ ``` typescript
931+ interface YasqeConfig {
932+ // ... other config options
933+
934+ // Function to create a shareable link (required to show share button)
935+ createShareableLink? : (yasqe : Yasqe ) => string ;
936+
937+ // Optional URL shortener function
938+ createShortLink? : (yasqe : Yasqe , longUrl : string ) => Promise <string >;
939+
940+ // Function to consume/parse shared links
941+ consumeShareLink? : (yasqe : Yasqe ) => void ;
942+ }
943+ ```
944+
945+ ** Basic Share Configuration:**
946+
947+ ``` javascript
948+ import Yasqe from ' @matdata/yasqe' ;
949+
950+ const yasqe = new Yasqe (document .getElementById (' yasqe' ), {
951+ requestConfig: {
952+ endpoint: ' https://dbpedia.org/sparql' ,
953+ method: ' POST'
954+ },
955+
956+ // Enable share button with URL generation
957+ createShareableLink : (yasqe ) => {
958+ const query = yasqe .getValue ();
959+ const endpoint = yasqe .getRequestConfig ().endpoint ;
960+
961+ // Create shareable URL with query parameters
962+ const params = new URLSearchParams ({
963+ query: query,
964+ endpoint: endpoint
965+ });
966+
967+ return ` ${ window .location .origin }${ window .location .pathname } ?${ params .toString ()} ` ;
968+ },
969+
970+ // Parse shared URLs on page load
971+ consumeShareLink : (yasqe ) => {
972+ const params = new URLSearchParams (window .location .search );
973+ const query = params .get (' query' );
974+ const endpoint = params .get (' endpoint' );
975+
976+ if (query) yasqe .setValue (query);
977+ if (endpoint) {
978+ yasqe .setRequestConfig ({
979+ ... yasqe .getRequestConfig (),
980+ endpoint: endpoint
981+ });
982+ }
983+ }
984+ });
985+ ```
986+
987+ ** URL Shortener Configuration (Kutt Example):**
988+
989+ Configure a URL shortener service to create shorter, more shareable links. This example shows integration with [ Kutt] ( https://kutt.it ) , but any URL shortener API can be used.
990+
991+ ``` javascript
992+ import Yasqe from ' @matdata/yasqe' ;
993+
994+ const yasqe = new Yasqe (document .getElementById (' yasqe' ), {
995+ requestConfig: {
996+ endpoint: ' https://dbpedia.org/sparql'
997+ },
998+
999+ // Basic shareable link creation
1000+ createShareableLink : (yasqe ) => {
1001+ const query = yasqe .getValue ();
1002+ const config = yasqe .getRequestConfig ();
1003+
1004+ const params = new URLSearchParams ({
1005+ query: query,
1006+ endpoint: config .endpoint || ' '
1007+ });
1008+
1009+ return ` ${ window .location .origin }${ window .location .pathname } ?${ params .toString ()} ` ;
1010+ },
1011+
1012+ // URL shortener integration (Kutt example)
1013+ createShortLink: async (yasqe , longUrl ) => {
1014+ const KUTT_API_URL = ' https://kutt.it/api/v2/links' ;
1015+ // Important: Load API key from a secure config or environment variable
1016+ // Never hardcode real API keys in source code!
1017+ // Example: Load from window.__CONFIG__ set by server-rendered template
1018+ const KUTT_API_KEY = window .__CONFIG__ ? .KUTT_API_KEY ;
1019+
1020+ if (! KUTT_API_KEY ) {
1021+ throw new Error (' Kutt API key not configured. Load it from a secure config or environment variable.' );
1022+ }
1023+
1024+ try {
1025+ const response = await fetch (KUTT_API_URL , {
1026+ method: ' POST' ,
1027+ headers: {
1028+ ' Content-Type' : ' application/json' ,
1029+ ' X-API-Key' : KUTT_API_KEY
1030+ },
1031+ body: JSON .stringify ({
1032+ target: longUrl,
1033+ // Optional: custom short code
1034+ // customurl: 'my-custom-code',
1035+ // Optional: domain (if using custom domain)
1036+ // domain: 'example.com',
1037+ // Optional: expiration
1038+ // expire_in: '2 hours'
1039+ })
1040+ });
1041+
1042+ if (! response .ok ) {
1043+ const error = await response .json ();
1044+ throw new Error (error .message || ' Failed to shorten URL' );
1045+ }
1046+
1047+ const data = await response .json ();
1048+ return data .link ; // Returns shortened URL
1049+
1050+ } catch (error) {
1051+ console .error (' URL shortening error:' , error);
1052+ throw error; // Error will be displayed to user
1053+ }
1054+ },
1055+
1056+ consumeShareLink: (yasqe ) => {
1057+ const params = new URLSearchParams (window .location .search );
1058+ const query = params .get (' query' );
1059+ if (query) yasqe .setValue (query);
1060+ }
1061+ });
1062+ ` ` `
1063+
1064+ **Other URL Shortener Examples:**
1065+
1066+ *YOURLS (Your Own URL Shortener):*
1067+ ` ` ` javascript
1068+ createShortLink: async (yasqe , longUrl ) => {
1069+ const YOURLS_API_URL = ' https://your-domain.com/yourls-api.php' ; // Your YOURLS instance
1070+ const YOURLS_SIGNATURE = ' your-signature-token' ; // Found in YOURLS admin > Tools
1071+
1072+ try {
1073+ const params = new URLSearchParams ({
1074+ signature: YOURLS_SIGNATURE ,
1075+ action: ' shorturl' ,
1076+ url: longUrl,
1077+ format: ' json' ,
1078+ // Optional: custom keyword
1079+ // keyword: 'my-custom-keyword'
1080+ });
1081+
1082+ const response = await fetch (` ${ YOURLS_API_URL } ?${ params .toString ()} ` , {
1083+ method: ' GET'
1084+ });
1085+
1086+ if (! response .ok ) {
1087+ throw new Error (` HTTP error! status: ${ response .status } ` );
1088+ }
1089+
1090+ const data = await response .json ();
1091+
1092+ if (data .status === ' fail' ) {
1093+ throw new Error (data .message || ' Failed to shorten URL' );
1094+ }
1095+
1096+ return data .shorturl ; // Returns shortened URL
1097+
1098+ } catch (error) {
1099+ console .error (' YOURLS shortening error:' , error);
1100+ throw error;
1101+ }
1102+ }
1103+ ` ` `
1104+
1105+ **Note:** YOURLS can authenticate using either a signature token (recommended) or username/password. The signature token is more secure and can be found in your YOURLS admin panel under Tools > Signature Token.
1106+
1107+ *TinyURL:*
1108+ ` ` ` javascript
1109+ createShortLink: async (yasqe , longUrl ) => {
1110+ try {
1111+ const response = await fetch (
1112+ ` https://tinyurl.com/api-create.php?url=${ encodeURIComponent (longUrl)} `
1113+ );
1114+
1115+ if (! response .ok ) {
1116+ throw new Error (` TinyURL request failed with status ${ response .status } ` );
1117+ }
1118+
1119+ const shortUrl = await response .text ();
1120+
1121+ // Basic validation: ensure the response is a valid TinyURL link
1122+ let parsedUrl;
1123+ try {
1124+ parsedUrl = new URL (shortUrl);
1125+ } catch {
1126+ throw new Error (' TinyURL response was not a valid URL' );
1127+ }
1128+
1129+ if (! / ^ https? :\/\/ (www\. )? tinyurl\. com\/ / .test (parsedUrl .href )) {
1130+ throw new Error (' TinyURL response did not contain a TinyURL link' );
1131+ }
1132+
1133+ return parsedUrl .href ;
1134+ } catch (error) {
1135+ console .error (' TinyURL shortening error:' , error);
1136+ throw error;
1137+ }
1138+ }
1139+ ` ` `
1140+
1141+ *Bitly:*
1142+ ` ` ` javascript
1143+ createShortLink: async (yasqe , longUrl ) => {
1144+ // Load token from secure config
1145+ const BITLY_TOKEN = window .__CONFIG__ ? .BITLY_TOKEN ;
1146+
1147+ if (! BITLY_TOKEN ) {
1148+ throw new Error (' Bitly token not configured' );
1149+ }
1150+
1151+ try {
1152+ const response = await fetch (' https://api-ssl.bitly.com/v4/shorten' , {
1153+ method: ' POST' ,
1154+ headers: {
1155+ ' Authorization' : ` Bearer ${ BITLY_TOKEN } ` ,
1156+ ' Content-Type' : ' application/json'
1157+ },
1158+ body: JSON .stringify ({ long_url: longUrl })
1159+ });
1160+
1161+ if (! response .ok ) {
1162+ throw new Error (` Bitly API request failed with status ${ response .status } ` );
1163+ }
1164+
1165+ const data = await response .json ();
1166+
1167+ if (! data || typeof data .link !== ' string' ) {
1168+ throw new Error (' Bitly API response missing expected "link" property' );
1169+ }
1170+
1171+ return data .link ;
1172+ } catch (error) {
1173+ console .error (' Failed to create Bitly short link:' , error);
1174+ throw error;
1175+ }
1176+ }
1177+ ` ` `
1178+
1179+ *Custom Backend:*
1180+ ` ` ` javascript
1181+ createShortLink: async (yasqe , longUrl ) => {
1182+ const response = await fetch (' /api/shorten' , {
1183+ method: ' POST' ,
1184+ headers: { ' Content-Type' : ' application/json' },
1185+ body: JSON .stringify ({ url: longUrl })
1186+ });
1187+
1188+ const data = await response .json ();
1189+ return data .shortUrl ;
1190+ }
1191+ ` ` `
1192+
1193+ **Share Button Features:**
1194+
1195+ When the share button is enabled (by configuring ` createShareableLink` ), users can:
1196+
1197+ 1. **Copy URL** - Copies the shareable URL to clipboard
1198+ 2. **Shorten URL** - Creates and copies a shortened URL (only shown if ` createShortLink` is configured)
1199+ 3. **Copy cURL** - Generates a cURL command with all headers and authentication
1200+ 4. **Copy PowerShell** - Generates a PowerShell ` Invoke- WebRequest` command
1201+ 5. **Copy wget** - Generates a wget command
1202+
1203+ All command formats include:
1204+ - Complete SPARQL query
1205+ - Endpoint URL
1206+ - HTTP method (GET/POST)
1207+ - All configured headers
1208+ - Accept header (based on query type: JSON for SELECT/ASK, text/turtle for CONSTRUCT/DESCRIBE)
1209+ - Authentication credentials (with security warning)
1210+ - Output file specification (PowerShell only, with appropriate extension based on Accept header)
1211+
1212+ **Security Considerations:**
1213+
1214+ ⚠️ When users copy command-line formats (cURL, PowerShell, wget) that include authentication credentials, YASQE displays a warning toast notification. This helps prevent accidental sharing of sensitive credentials.
1215+
1216+ **Best Practices:**
1217+
1218+ 1. **Store API keys securely** - Never commit API keys to version control
1219+ 2. **Use environment variables** - Load API keys from environment or configuration
1220+ 3. **Implement rate limiting** - Prevent abuse of URL shortener services
1221+ 4. **Handle errors gracefully** - Provide user-friendly error messages
1222+ 5. **Consider privacy** - Be transparent about what data is included in shared URLs
1223+
1224+ **Troubleshooting:**
1225+
1226+ - If the share button doesn't appear, ensure ` createShareableLink` is configured
1227+ - If "Shorten URL" doesn't appear, check that ` createShortLink` is configured
1228+ - Check browser console for API errors when shortening fails
1229+ - Verify API keys and endpoints are correct
1230+ - Ensure CORS is properly configured for your URL shortener API
1231+
9231232### YASR Configuration
9241233
9251234YASR (results viewer) specific configuration options:
0 commit comments