# Plugin Templates

## Method of a component

In this example - `render`

```javascript
const render = (args, callback, instance) => (
   <>
       { callback.apply(instance, args) }
   </>
);

export default {
   'Component/NAME/Component': {
       'member-function': {
           render
       }
   }
};
```

## Container functions

Common case - when you need to pass an additional function from parent to child

```javascript
export class NAMEContainerPlugin {
   containerFunctions = (originalMember, instance) => ({
       ...originalMember,
       handleSomething: this.handleSomething.bind(instance)
   });

   handleSomething(arg) {
       console.log(arg);
   }
}

const { containerFunctions } = new NAMEContainerPlugin();

export default {
   'Component/NAME/Container': {
       'member-property': {
           containerFunctions
       }
   }
};
```

## Prop types

You need to add an additional prop to `propTypes` after passing an additional prop to the component? No problem!&#x20;

```javascript
import PropTypes from 'prop-types';

const propTypes = (originalMember) => ({
   ...originalMember,
   handleSomething: PropTypes.func.isRequired
});

export default {
   'Component/NAME/Component': {
       'static-member': {
           propTypes
       }
   }
};
```

## Default props

Not required new propType - do this.

```javascript
const defaultProps = (originalMember) => ({
   ...originalMember,
   pluginProp: 'PluginProp'
});

export default {
   'Component/NAME/Container': {
       'static-member': {
           defaultProps
       }
   }
};
```

## More state

Additional fields for the state.

```javascript
const state = (originalMember) => ({
   ...originalMember,
   PluginState: 'PluginState'
});

export default {
   'Component/NAME/Container': {
       'member-property': {
           state
       }
   }
};
```

## Adding a Reducer to the Redux Store

Add reducers to the application as follows.&#x20;

```javascript
import { NAMEReducer } from '../store/NAME;

const getStaticReducers = (args, callback, instance) => ({
   ...callback(...args),
   NAMEReducer
});

export const config = {
   'Store/Index/getReducers': {
       function: getStaticReducers
   }
};

export default config;
```

## Query fields

Additional query field shown below!

```javascript
const _getMETHODFields = (args, callback, instance) => [
   ...callback.apply(instance, args),
   'field_name'
];

export default {
   'Query/NAME': {
       'member-function': {
           _getMETHODFields
       }
   }
};
```

## Reducer Initial State

```javascript
const getInitialState = (args, callback, instance) => (
    {
        ...callback(...args),
        new_state: 'true'
    }
);

export default {
    'Store/NAME/Reducer/getInitialState': {
        function: getInitialState
    }
};
```

## mapStateToProps

Connect an additional piece of state to the component

```javascript
const mapStateToProps = (args, callback, instance) => {
   const [state] = args; 

   return {
       ...callback(...args),
       pluginProp: state.SomeReducer.someState
   };
};

export default {
   'Component/NAME/Container/mapStateToProps': {
       function: mapStateToProps
   }
};
```

## mapDispatchToProps

Connect an additional dispatch function to the component

```javascript
const { letsDoSomething } = import('Store/STORENAME/STORENAME.action');

const mapDispatchToProps = (args, callback, instance) => {
   const [dispatch] = args;

   return {
       ...callback(...args),
       doSomething: (value) => dispatch(letsDoSomething(value))
   };
};

export default {
   'Component/NAME/Container/mapDispatchToProps': {
       function: mapDispatchToProps
   }
};
```

## Adding a Route to the Router

Note how we use async `import(...)` statement here in order to optimize bundle sizes!

```javascript
import { lazy } from 'react';
import { Route } from 'react-router-dom';

import { withStoreRegex } from 'Component/Router/Router.component';

export const YourPage = lazy(() => import(
    /* webpackMode: "lazy", webpackChunkName: "extension-name" */ 
    '../route/YourPage'
));

const SWITCH_ITEMS_TYPE = (originalMember) => [
   ...originalMember,
   {
       component: (
           <Route
             path={ withStoreRegex('/path') }
             render={ (props) => <YourPage { ...props } /> }
           />
       ),
       position: 100
   }
];

export const config = {
   'Component/Router/Component': {
       'member-property': {
           SWITCH_ITEMS_TYPE
       }
   }
};

export default config;
```

## Extending maps

Example: creating a new tab in MyAccount

```javascript
import { lazy } from 'react';

import { 
    MY_TAB_PATH,
    MY_TAB_NAME
} from '../component/MyAccountCustomTab/MyAccountCustomTab.config';

import MyAccountCustomTab from '../component/MyAccountCustomTab';

const renderMap = (originalMember) => ({
   [MY_TAB_NAME]: MyAccountCustomTab,
   ...originalMember,
});

const tabMap = (originalMember) => ({
   ...originalMember,
   [MY_TAB_NAME]: {
       url: `/${ MY_TAB_PATH }`,
       name: __('My Tab')
   }
});

export default {
   'Route/MyAccount/Container': {
       'static-member': {
           tabMap
       }
   },
   'Route/MyAccount/Component': {
       'member-property': {
           renderMap
       }
   }
};
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.create-scandipwa-app.com/extensions/application-plugins/templates.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
